2010-05-18 50 views
1

鑑於日期列表遞歸算法合併/摺疊日期列表插入範圍

12/07/2010 
13/07/2010 
14/07/2010 
15/07/2010 
12/08/2010 
13/08/2010 
14/08/2010 
15/08/2010 
19/08/2010 
20/08/2010 
21/08/2010 

我找對遞歸算法的僞代碼指針(我可以翻譯成的FileMaker自定義函數)用於生產範圍列表,例如

12/07/2010 to 15/07/2010, 12/08/2010 to 15/08/2010, 19/08/2010 to 20/08/2010 

該列表被預先排序和去重複。我試着從第一個價值觀和第一個工作轉向開始,最後一個價值觀和倒退工作,但我似乎無法使其發揮作用。有了這些令人沮喪的一天......這將是很好,如果簽名是像

CollapseDateList(dateList, separator, ellipsis) 

:-)

回答

1

主程序會是這個樣子:

List<String> list = new ArrayList<String>(); 

String firstDate = dateList[0]; 
String lastDate = dateList[0]; 
String currentDate = dateList[0]; 

for (int i = 1; i < dateList.length(); i++) { 
    if (dateDiff(dateList[i], currentDate) == 1) { 
     lastDate = dateList[i]; 
    } else { 
     list.add(firstDate + separator + lastDate); 
     firstDate = dateList[i]; 
     lastDate = dateList[i]; 
    } 
    currentDate = dateList[i]; 
} 
list.add(firstDate + separator + lastDate); 

我假設你有一些函數告訴你兩個日期是否連續。

+0

不確定這是遞歸嗎? – Dycey 2010-05-18 14:30:20

+0

@Dycey:除非您考慮循環遞歸,否則僞代碼不是遞歸的。 – 2010-05-18 14:47:29

+0

這是一個恥辱,因爲我要求遞歸代碼(標題中的第一個單詞:-))!我並不是懶惰--FileMaker自定義函數使用各種函數式語言,因此您需要使用遞歸來代替循環。 – Dycey 2010-05-18 15:28:15

1

下面是執行該工作的遞歸FileMaker代碼。基本方法是在必要時進行替換,計算一個值中最後一個日期(最右邊的單詞)的日期。這樣它可以決定何時檢查下一個值是否仍然是第一個範圍的一部分,或者將第一個範圍標記爲已完成,並將其重點放在其餘的值上。希望它可以幫助別人。

// CollapseDateList(dates, comma, dash) 

Let(
    countDates = ValueCount (dates); 

    If (
    countDates < 2 ; dates; // return the dates we've been given... 

    Let(
     [ 
     start_date = GetAsDate(LeftWords(GetValue (dates ; 1); 1)); 
     date_1 = GetAsDate(RightWords(GetValue (dates ; 1); 1)); 
     date_2 = GetAsDate(GetValue (dates ; 2)); 
     date_3 = GetAsDate(GetValue (dates ; 3)); 
     dv_1 = GetAsNumber(date_1); 
     dv_2 = GetAsNumber(date_2); 
     dv_3 = GetAsNumber(date_3); 
     twoFollowsOne = (dv_2 = dv_1 + 1); 
     threeFollowsTwo = (dv_3 = dv_2 + 1) 
     ]; 

     // compare dates 
     Case(
     // only two dates in list 
     countDates = 2; 
      if (
      twoFollowsOne; 
      start_date & dash & date_2; 
      GetValue (dates ; 1) & comma & date_2 
     ); 

     // first three values are sequential 
     threeFollowsTwo and twoFollowsOne; 
      CollapseDateList(start_date & dash & date_3 & ¶ & RightValues(dates; countDates - 3); comma; dash); 

     // first two values are sequential only 
     not threeFollowsTwo and twoFollowsOne; 
      start_date & dash & date_2 & comma & CollapseDateList( RightValues( dates; countDates - 2); comma; dash); 

     // first two values are not sequential 
     // default 
     GetValue (dates ; 1) & comma & CollapseDateList(RightValues(dates; countDates - 1); comma; dash) 
    ) 
    ) 
) 
)