2010-12-04 13 views
2

私はいくつかの操作を行うれているIDのセットを持っている:C#で拡張可能なキューのようなものはありますか?

Queue<string> queue = new Queue<string>(); 
queue.Enqueue("1"); 
queue.Enqueue("2"); 
... 
queue.Enqueue("10"); 

foreach (string id in queue) 
{ 
    DoSomeWork(id); 
} 

static void DoSomeWork(string id) 
{ 
    // Do some work and oooo there are new ids which should also be processed :) 
    foreach(string newID in newIDs) 
    { 
     if(!queue.Contains(newID)) queue.Enqueue(newID); 
    } 
} 

もメインのforeachループBEI処理されるDoSomeWork()queueにいくつかの新しいアイテムを追加することが可能ですか?

答えて

1

使用デキュー。基本的なコンテナが変更されると、ほとんどの列挙子は無効になります。エン/デキューは、キュー上の自然な操作です。そうでなければ、あなたはアイテムがすでにHashSet<T>が高速なソリューションで処理されたかどうかを確認するにはList<T>または

while(queue.Count>0) 
{ 
    var value=queue.Dequeue(); 
    ... 
} 

HashSet<T>を使用することができます。これらのケースでは、通常、HashSetとQueueの組み合わせを使用します。 HashSetのチェックと追加がO(1)であるため、このソリューションの利点はO(n)です。 QueueContainsがO(n)であるため、元のコードはO(n^2)でした。

Queue<string> queue=new Queue<string>(); 
HashSet<string> allItems=new HashSet<string>(); 

void Add(string item) 
{ 
    if(allItems.Add(item)) 
    queue.Enqueue(item); 
} 

void DoWork() 
{ 
    while(queue.Count>0) 
    { 
     var value=queue.Dequeue(); 
     ... 
    } 
} 
+0

どうでしょうHashSetのと、この作品? – Makara

+0

@Makara未処理アイテムを保持するためにキューを使用する例と、重複を避けるためにHashSetを追加した例を追加しました。 – CodesInChaos

0

一般的に、ループの反復では、より多くの作業を追加できます。引数としてメソッドにキューを渡し、追加するだけでうまくいくはずです。

問題は、OUはデキューを使用しなければならないということである。代わりのforeachループの

while(queue.Count>0) { 
    DoSomeWork(queue.Dequeue()); 
} 
3

あなたがやっていることは、変化するコレクションのイテレータを使用することです。これは悪いことです。コレクションの中には、これを行うときに例外をスローするものがあります(たとえば、列挙中にコレクションを変更しないなど)。

にも新しいアイテムを使用しない、次のアプローチを、使用してください:

while (queue.Count > 0) 
{ 
    DoSomeWork(queue.Dequeue()); 
} 
+0

これはHashSet でも可能ですか? – Makara

+0

いいえ、ただし、リストインデックスを使用する場合は、 'List <>'を使用してください。もちろん、どの項目がすでに処理されているか(セットを使用しているか)、どの項目を処理(キュー)する必要があるかを知るために、 'HashSet <>'と 'Queue <>'の両方を持つこともできます。 – Lucero

関連する問題