Рекурсивный алгоритм для коалесценции / разрушения списка дат в диапазон

голоса
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 )

:-)

Задан 18/05/2010 в 13:58
источник пользователем
На других языках...                            


2 ответов

голоса
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);

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

Ответил 18/05/2010 в 15:09
источник пользователем

голоса
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 )
      ) 
    )
  )
)
Ответил 18/05/2010 в 16:26
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more