[英]Issue with Time Calculation in Java
在篩選測試中,我被要求編寫一個程序來獲得一天中可用的最大空閑時間。
例如:
輸入: “10:00AM-12:30PM”,“02:00PM-02:45PM”,“09:10AM-09:50AM”
預計 Output: 01:30
這些時間范圍可能不按遞增順序排列。
對於這個問題,我嘗試在 java 中編寫一個小代碼:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.time.Duration;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.*;
public class TimeDiff {
public static void main(String[] args) throws NullPointerException {
String accStr = null;
System.out.println("Enter day time entries : ");
try (BufferedReader br = new BufferedReader(new InputStreamReader(System.in))) {
accStr = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
String unQuoted = accStr.replace("\"", "");
String[] inputSplit = unQuoted.split(",");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("hh:mma");
Map<LocalTime, LocalTime> timeMap = new TreeMap<>();
for (String x : inputSplit) {
String[] furtherSplit = x.split("-");
timeMap.put(LocalTime.parse(furtherSplit[0], dateTimeFormatter), LocalTime.parse(furtherSplit[1], dateTimeFormatter));
}
Iterator iterator = timeMap.entrySet().iterator();
List<Long> duration = new ArrayList<Long>();
LocalTime[][] convertedMaptoArray = new LocalTime[timeMap.size()][2];
int rowIndex = 0;
while (iterator.hasNext()) {
int colIndex = 0;
Map.Entry pair = (Map.Entry) iterator.next();
//System.out.println(pair.getKey() + " " + pair.getValue());
convertedMaptoArray[rowIndex][colIndex] = (LocalTime) pair.getKey();
convertedMaptoArray[rowIndex][colIndex+1]=(LocalTime)pair.getValue();
rowIndex++;
}
LocalTime previousRecordEndTime = null;
LocalTime currentRecordStartTime = null;
for(int i= 0; i<=convertedMaptoArray.length-1;i++)
{
currentRecordStartTime = convertedMaptoArray[i][0];
//System.out.println("current :" +currentRecordStartTime);
if(i>0){
previousRecordEndTime = convertedMaptoArray[i-1][1];
//System.out.println("Previous : " + previousRecordEndTime);
duration.add(ChronoUnit.MINUTES.between(previousRecordEndTime, currentRecordStartTime));
}
}
System.out.println("Longest duration : " + LocalTime.MIN.plus(Duration.ofMinutes(Collections.max(duration))).toString());
}
}
我被篩選了,但我對上面的代碼有幾個問題:
請幫忙。 提前致謝。
我認為你正在破壞 KISS(使事情過於復雜),同時混合了 2 個截然不同的職責:解析輸入的職責和計算間隔的職責 - 你只對最短的時間感興趣,因此存儲所有內容沒有必要。
輸入是否假定為通過控制台輸入的字符串?
我將其分解為以下方法:
// 01:00AM -> 60
private static int timeStringToMinutesFromMidnight(String time)
// 60 -> 01:00
private static String minutesToHoursAndMinutes(int minutes)
// 11:00AM-11:30AM -> 660 690 added to list
private static void parseInterval(String interval, List<Integer> minutes)
(在之前的編輯中,我有timeStringIntervalToMinutes
,但我誤讀了問題並且計算了錯誤的輸出)。
您在這里不需要任何復雜的數據結構:一個簡單的List
可以讓您完成所需的一切。 對其進行排序比使用TreeMap
或TreeSet
更容易 - 是的,它們進行自己的排序,但在占用空間和訪問速度方面也更重。
完整代碼(導入java.util.*
和java.io.*
):
// 01:00AM -> 60
private static int timeStringToMinutesFromMidnight(String time) {
int hours = Integer.parseInt(time.substring(0,"hh".length()));
int minutes = Integer.parseInt(time.substring("hh:".length(), "hh:mm".length()));
boolean afternoon = time.substring("hh:mm".length()).equalsIgnoreCase("PM");
if (afternoon && hours != 12) {
hours += 12;
}
return hours * 60 + minutes;
}
// 60 -> 01:00
private static String minutesToHoursAndMinutes(int minutes) {
int hours = minutes / 60;
minutes = minutes % 60;
return String.format("%02d:%02d", hours, minutes);
}
// 11:00AM-11:30AM -> 660 690 added to list
private static void parseInterval(String interval, List<Integer> minutes) {
String[] parts = interval.split("-");
int start = timeStringToMinutesFromMidnight(parts[0]);
int end = timeStringToMinutesFromMidnight(parts[1]);
if (end < start) {
throw new IllegalArgumentException("interval " + interval + " has end<start");
}
minutes.add(start);
minutes.add(end);
}
// Input: "10:00AM-12:30PM","02:00PM-02:45PM","09:10AM-09:50AM"
// Expected Output: 01:30
public static void main(String ... args) {
List<Integer> endpoints = new ArrayList<>();
try (Scanner sc = new Scanner(System.in).useDelimiter("[,\"]+")) {
while (sc.hasNext()) {
parseInterval(sc.next(), endpoints);
}
}
if (endpoints.isEmpty()) {
System.out.println("No intervals found");
return;
}
// sort the endpoints (assuming that no intervals overlap, intervals will not be broken)
Collections.sort(endpoints);
int largest = -1;
for (int i=1; i<endpoints.size()-1; i+=2) {
largest = Math.max(largest, endpoints.get(i+1) - endpoints.get(i));
}
System.out.println(minutesToHoursAndMinutes(largest));
}
我建議:
Map
用於您的條目。 使用一對 class 或定義一個TimeRange
class 可以容納兩個LocalTime
對象。 然后收集這些。Map
,也不要使用原始的Map.Entry
。 參數化為Map.Entry<LocalTIme, LocalTime>
。 同樣參數化你的迭代器。 (另一方面, new ArrayList<Long>()
中的類型參數是多余的;只是new ArrayList<>()
是常規的。)Long
用於持續時間。 只需在整個過程中使用Duration
class。 使用其compareTo
方法進行比較。Collections.max()
。 我會傳遞從Arrays.asList()
獲得的列表,或者甚至更好,避免 arrays 並將持續時間專門保留在列表中。 然后當然是適當的Comparator
實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.