代码之家  ›  专栏  ›  技术社区  ›  Dycey

将日期列表合并/折叠为范围的递归算法

  •  1
  • Dycey  · 技术社区  · 14 年前

    给出日期列表

    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
    

    我正在寻找指向递归伪代码算法(我可以将其转换为文件生成器自定义函数)的指针,以生成范围列表,即。

    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 )
    

    -)

    2 回复  |  直到 14 年前
        1
  •  1
  •   Gilbert Le Blanc    14 年前

    主要程序如下:

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

    我假设你有一个函数,告诉你两个日期是否连续。

        2
  •  1
  •   Dycey    14 年前

    这是执行该任务的递归文件生成器代码。基本方法是在必要的情况下进行替换,从值中的最后一个日期(最右边的单词)开始计算日期。这样,它就可以决定何时检查下一个值是否仍然是第一个范围的一部分,或者将第一个范围标记为已完成,并将焦点集中在其余值上。希望它能帮助别人。

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