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

Sorry dudes, but I do not pretty much like your solutions. I think you should create a HashTable with your dates. You can do this by interating only once the working days.

Then, you interate the full range of of days and for every one you query in the hashtable if the date is there or not, by using

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

Simple, elegant and fast.

I think your solution uses an exponencial time, this one is lineal or logarithmical (which is actually a good thing).

于 2010-04-10T14:13:03.193 に答える
3

有効な日付のリストを作成し、LINQのEnumerable.Except拡張メソッドを使用してそのリストからマシンの日コレクションを減算します。このようなもの:

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 に答える
0

私はあなたが働いている日と働いていない日のリストが欲しいとは思わない。

質問のタイトルは、システムが特定の日に稼働していたかどうかを知りたいことを示唆しています。稼働率を計算することも合理的と思われます。これらのどちらも、間隔内のすべての時点のリストを作成する必要はありません。

サービス時間を並べ替えます。最初の質問については、気になる日付のBinarySearchを実行し、前のエントリがシステムのメンテナンスをオフラインにしたのか、サービスに戻したのかを確認します。稼働時間の割合については、ペアごとに(メンテナンスのためにダウン、サービスを復元)、減算を使用してメンテナンスの期間を見つけ、これらを合計します。次に、減算を使用して、合計間隔の長さを見つけます。

あなたの質問が実際にあなたがメンテナンス間隔(または同等に使用間隔)を追跡していることを意味していなかったなら、あなたはこの答えを無視することができます。

于 2010-04-10T15:47:55.137 に答える
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 に答える