4

我有一个机器工作的日期列表,但它不包括机器停机的日期。我需要创建工作天数和未工作天数的列表。我不确定执行此操作的最佳方法。我已经开始递增一个范围的所有天数,并通过每次迭代整个列表来检查日期是否在列表中。我正在寻找一种更有效的方法来查找日期。

class machineday
{
 datetime WorkingDay;
}

class machinedaycollection : List<machineday>
{
public List<TimeCatEvent> GetAllByCat(string cat)
{
  _CategoryCode = cat;


  List<machineday> li = this.FindAll(delegate(machinedaydummy) { return true; });
  li.Sort(sortDate);
  return li;
}

int sortDate(machinedayevent1, machinedayevent2)
{
  int returnValue = -1;
  if (event2.date < event1.date)
  {
    returnValue = 0;
  }
  else if (event2.date == event1.date)
  {
    //descending
    returnValue = event1.date.CompareTo(event2.date);
  }
  return returnValue;
}
}
4

5 回答 5

6

对日期进行排序并在递增计数器的同时迭代结果列表。每当计数器与当前列表元素不匹配时,您就会发现列表中缺少日期。

List<DateTime> days = ...;
days.Sort();
DateTime dt = days[0].Date;
for (int i = 0; i < days.Length; dt = dt.AddDays(1))
{
    if (dt == days[i].Date)
    {
        Console.WriteLine("Worked: {0}", dt);
        i++;
    }
    else
    {
        Console.WriteLine("Not Worked: {0}", dt);
    }
}

(这假设列表中没有重复的日期。)

于 2010-04-10T13:48:41.003 回答
3

Enumerable.Except使用 LINQ 的扩展方法构建一个有效日期列表并从中减去您的机器日集合。像这样的东西:

IEnumerable<DateTime> dates = get_candidate_dates();
var holidays = dates.Except(machinedays.Select(m => m.WorkingDay));

get_candidate_dates()方法甚至可以是一个迭代器,它可以动态生成一个范围内的所有日期,而不是所有日期的预存储列表。

Enumerable 的方法相当聪明,通常会在性能方面做得不错,但是如果您想要最快的算法,这将取决于您计划如何使用结果。

于 2010-04-10T13:45:30.790 回答
3

对不起伙计们,但我不太喜欢你的解决方案。我认为您应该使用您的日期创建一个 HashTable。您可以通过仅在工作日进行一次交互来做到这一点。

然后,如果日期存在或不存在,您可以使用完整的日期范围以及您在哈希表中查询的每一天

myHashTable.ContainsKey(day); // this is efficient

简单、优雅、快速。

我认为您的解决方案使用指数时间,这是线性时间或对数时间(这实际上是一件好事)。

于 2010-04-10T14:13:03.193 回答
0

假设列表已排序并且机器大部分时间都在“工作”,您可以通过按月分组日期并跳过其间的日期来避免遍历所有日期。像这样的东西(你需要清理):

int chunksize = 60; // adjust depending on data
machineday currentDay = myMachinedaycollection[0];

for (int i = 0; i < myMachinedaycollection.Count; i += chunksize)  
{  
    if (currentDay.WorkingDay.AddDays(chunksize) != myMachinedaycollection[i + chunksize].WorkingDay)  
    {
        // write code to iterate through current chunk and get all the non-working days  
    }
    currentDay = myMachinedaycollection[i + chunksize];  
}  
于 2010-04-10T14:00:51.677 回答
0

我怀疑你想要一份工作天数和不工作天数的清单。

您的问题标题表明您想知道系统是否在特定日期启动。计算正常运行时间百分比似乎也是合理的。这些都不需要建立间隔中所有时间点的列表。

对服务时间进行排序。对于第一个问题,对您关心的日期进行 BinarySearch,并检查前面的条目是系统脱机维护还是重新投入使用。对于 % 正常运行时间,成对计算(停机维护,服务恢复),使用减法计算维护持续时间,然后将它们相加。然后用减法求总区间的长度。

如果您的问题实际上并不意味着您正在跟踪维护间隔(或等效的使用间隔),那么您可以忽略此答案。

于 2010-04-10T15:47:55.137 回答