2016-12-15 6 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

変更が簡単ではない理由は、「現在のサブ配列にすべての連続する要素が含まれていて、日付が「連続した要素」でないかどうかをチェックすることです。 Datesを「年の日」とか、それを潜在的に連続する要素にする何かを扱うことはできますが、これは簡単ではありません。 – alfasin

+0

はいこのコードを変更しましたが、そのコードは1か月間しか使用できません –

答えて

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を、DR

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

文字列!=日付

私はArraylist coを持っています日付を昇順に並べ替える。日付はこの形式のyyyy-MM-ddです。

つまり、ListのStringオブジェクトがあり、日付はありません。ここでの主な課題は、日付オブジェクトを取得して、それらの間の日数を計算できることです。

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); 

最長期間は日があります。= 2016年1月25日/ 2016年2月22日28

live code in IdeOne.comを参照してください。

+0

ありがとう@Basil Bourque –

関連する問題