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

创建“随时间”算法

  •  1
  • Icemanind  · 技术社区  · 15 年前

    我拥有的是一个LineItem对象和一个名为LineItems的集合,其中包含LineItem对象。我的LineItem对象有一个名为ItemDate(DateTime数据类型)的属性和另一个名为ItemAmount(decimal数据类型)的属性以及另一个名为ItemCategory(integer数据类型)的属性。

    我要做的是在我的collection对象中编写一个函数,它将返回整数类别,无论哪个类别的和(ItemAmount)最高。例如,如果我有:

    对象1:

    项目金额=50.00

    对象2:

    项目金额=25

    目标3:

    项目金额=535.00

    项目类别=2

    在这个例子中,函数应该返回2,因为ItemCategory 2的ItemAmount(535)大于ItemCategory 1(50+25=75)。

    我知道怎么做。但更难的是,我需要它能够随着时间的推移做到这一点,也就是说,如果一个量很大,比如535,但其他一些物体的量较小,但离更近的日期有更多,那么它就需要在技术上比其他量“大”。这几乎就像数量需要考虑到频率太多$每天发生的10个金额需要“大于”每年发生一次的500美元,即使500美元大于每天10美元。就像我需要通过一年的放大镜来观察一个月的数据。

    我希望这个问题有道理。

    2 回复  |  直到 15 年前
        1
  •  1
  •   Flynn1179    15 年前

    试试这个:

    class ListItem
    {
        internal DateTime When;
        internal decimal Amount;
        internal int Category;
    }
    
    class ListItems
    {
        internal List<ListItem> _items = new List<ListItem>();
        internal int GetCategory(DateTime from, DateTime to)
        {
            Dictionary<int, decimal> totals = _items
                .Where(y => y.When >= from && y.When < to)
                .GroupBy(x => x.Category)
                .ToDictionary(
                    category => category.Key,
                    category => category.Sum(item => item.Amount)
                );
            return totals.Keys
                .Where(category => totals[category] == totals.Values.Max())
                .First();
        }
    }
    

        2
  •  1
  •   comingstorm    15 年前

    听起来你可能想要一个旅行窗口总和:选择一个时间段(比如说,30天),并跟踪该窗口内的项目总数。

    为了实现一个移动窗口,您可以使用两个迭代器进入一个排序列表(以下是伪代码,而不是C#):

    // initialize
    acc= 0.0
    for(startP= SortedItems.begin; !startP.last; startP.next) {
      if(startP.item.time > graphstart - timewindow) { break }
    }
    for(endP= startP; !endP.last; endP.next) {
      acc += endP.item.value
      if(endP.item.time > graphstart) { break }
    }
    
    // main loop
    for(; !endP.last; endP.next) { // advance time window to next item
      endItem= endP.item
      endTime= endItem.time
      for(; !startP.last; startP.next) { // subtract items leaving time window
        startItem= startP.item
        startTime= startItem.time
        if(startTime > endTime - timewindow) { break }
        acc -= startItem.value
        output(startTime + timewindow, acc)  // register graph values coming down
      }
      acc += endItem.value
      output(endTime, acc)  // register graph value going up
    }
    
    推荐文章