2016-12-15 62 views
0

您好我有一個Arraylist包含日期遞增的順序。日期格式爲yyyy-MM-dd。現在我想找出Arraylist中最長的連續子序列。我在網上檢查瞭解決方案,但它們與int數組有關,我想查找日期數組。 代碼int數組:日期排列中最長的連續子序列

// Returns length of the longest contiguous subarray 
int findLength(int arr[], int n) 
{ 
int max_len = 1; // Initialize result 
for (int i=0; i<n-1; i++) 
{ 
    // Initialize min and max for all subarrays starting with i 
    int mn = arr[i], mx = arr[i]; 

    // Consider all subarrays starting with i and ending with j 
    for (int j=i+1; j<n; j++) 
    { 
     // Update min and max in this subarray if needed 
     mn = min(mn, arr[j]); 
     mx = max(mx, arr[j]); 

     // If current subarray has all contiguous elements 
     if ((mx - mn) == j-i) 
      max_len = max(max_len, mx-mn+1); 
    } 
} 
return max_len; // Return result 
} 

// Utility functions to find minimum and maximum of 
// two elements 
int min(int x, int y) { return (x < y)? x : y; } 
int max(int x, int y) { return (x > y)? x : y; } 
+0

它不直接修改的原因是這種方法檢查「當前子數組是否具有所有連續元素」,而日期不是「連續元素」。您可以將日期視爲「一年中的某些日子」或其他可能使其成爲潛在連續元素的其他內容,但這不是直截了當的。 – alfasin

+0

是的,我修改了這段代碼,但它只工作了一個月 –

回答

1

我解決了這個使用這個代碼,如果任何人面臨着同樣的問題,他們可以使用以下代碼:

private int getBest(){ 
    //Getting dates 
    ArrayList<Date> successDates = new ArrayList<>(); 
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()); 
    for(int i=0; i<successDays.size(); i++){ 
     try { 
      successDates.add(sdf.parse(successDays.get(i))); 
     } catch (ParseException e) { 
      e.printStackTrace(); 
     } 
    } 
    int max_len = 1; 
    for(int i=0; i<successDates.size(); i++){ 
     Date mn = successDates.get(i); 
     Date mx = successDates.get(i); 
     for(int j=i+1; j<successDates.size(); j++){ 
      if(mn.compareTo(successDates.get(j))>0){ 
       mn = successDates.get(j); 
      } 
      if(mx.compareTo(successDates.get(j))<0){ 
       mx = successDates.get(j); 
      } 
      if(getDaysBetweenDates(mn, mx) == j-i){ 
       if(max_len < getDaysBetweenDates(mn, mx)+1){ 
        max_len = getDaysBetweenDates(mn, mx) + 1; 
       } 
      } 
     } 
    } 
    return max_len; 
} 

private int getDaysBetweenDates(Date min, Date max){ 
    Calendar mn = Calendar.getInstance(); 
    mn.setTime(min); 

    Calendar mx = Calendar.getInstance(); 
    mx.setTime(max); 

    long msDiff = mx.getTimeInMillis() - mn.getTimeInMillis(); 
    return (int)TimeUnit.MILLISECONDS.toDays(msDiff); 
} 
+2

FYI,舊的日期 - 時間類,例如['java.util.Date'](https://docs.oracle.com/javase/8/ docs/api/java/util/Date.html),['java.util.Calendar'](https://docs.oracle.com/javase/8/docs/api/java/util/Date.html),和'java.text.SimpleTextFormat'現在是[legacy](https://en.wikipedia.org/wiki/Legacy_system),由[java.time]代替(https://docs.oracle.com/javase/ 8/docs/api/java/time/package-summary.html)類。 –

5

TL;博士

ChronoUnit.DAYS.between ( 
    LocalDate.parse(previousString) , 
    LocalDate.parse(currentString) 
) 

字符串!= date

我有一個Arraylist co不斷增加日期。日期的格式爲yyyy-MM-dd。

這意味着你有一個String對象的List,而不是日期。這裏的主要挑戰是獲取日期對象,以便可以計算它們之間的日期。

java.time

現代的方式是與取代的麻煩舊的遺留類(DateCalendar等)java.time類。

您的輸入字符串碰巧符合標準ISO 8601格式。在解析/生成字符串時,java.time類默認情況下默認使用ISO 8601格式。所以不需要指定formatting pattern

List<String> inputs = new ArrayList<>(); 
inputs.add ("2016-01-23"); 
inputs.add ("2016-01-25"); 
inputs.add ("2016-02-22"); // End of longest period between dates. 
inputs.add ("2016-02-25"); 
inputs.add ("2016-02-28"); 

LocalDate類表示沒有時間一天和不同時區的日期,唯一的價值。

此示例代碼的策略是計算每個LocalDate(從每個傳入的字符串解析)和之前的LocalDate之間的天數。如果超過目前爲止所看到的最長時間,則忘記舊的最長時間並記住當前循環的數據。

LocalDate longestStart = null; 
LocalDate longestStop = null; 
LocalDate previousDate = null; 
long longestInDays = 0; 

ChronoUnitenum具有方便的方法,如計算經過的天。

for (String input : inputs) { 
    LocalDate currentDate = LocalDate.parse (input); 
    if (null == previousDate) { // First loop. 
     previousDate = currentDate; 
     continue; // Skip the rest of this first loop. 
    } 
    long currentDays = ChronoUnit.DAYS.between (previousDate , currentDate); 
    if (currentDays > longestInDays) { 
     // If the current loop exceeds previous longest, remember this one as longest. 
     longestInDays = currentDays; 
     longestStart = previousDate; 
     longestStop = currentDate; 
    } 
    // Prepare for next loop. 
    previousDate = currentDate; 
} 

將結果轉儲到控制檯。

System.out.println ("Longest period has days: " + longestInDays + " = " + longestStart + "/" + longestStop); 

最長週期具有天:28 = 2016年1月25日/ 2016年2月22日

live code in IdeOne.com見。

+0

謝謝@Basil Bourque –