2010-05-18 3 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); 

I Предполагая, что у вас есть функция, которая говорит вам, являются ли две даты последовательными или нет.

+0

Не знаете, как это рекурсивно? – Dycey

+0

@Dycey: псевдокод не является рекурсивным, если не считать рекурсивный цикл. –

+0

Какой позор, когда я просил рекурсивный код (первое слово в названии :-))! Я не был тупым - пользовательские функции FileMaker используют функциональный язык, поэтому вам нужно использовать рекурсию вместо циклов. – Dycey

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

 Смежные вопросы

  • Нет связанных вопросов^_^