日期排列中最长的连续子序列

问题描述:

您好我有一个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

是的,我修改了这段代码,但它只工作了一个月 –

我解决了这个使用这个代码,如果任何人面临着同样的问题,他们可以使用以下代码:

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)类。 –

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 –