【问题标题】:Is there anything like a expandable Queue in C#?C# 中有类似可扩展队列的东西吗?
【发布时间】:2010-12-04 12:47:18
【问题描述】:

我有一组 ID 用于执行一些操作:

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

是否可以在DoSomeWork() 中向queue 添加一些新项目,这些项目也将在主foreach 循环中处理?

【问题讨论】:

    标签: c# .net loops queue


    【解决方案1】:

    您正在做的是在不断变化的集合上使用迭代器。这是不好的做法,因为某些集合在执行此操作时会抛出异常(例如,在枚举期间集合不应更改)。

    使用以下方法,它也使用新项目:

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

    【讨论】:

    • HashSet 也可以吗?
    • 否,但如果您使用列表索引,则使用 List&lt;&gt;。当然,您也可以同时拥有HashSet&lt;&gt;Queue&lt;&gt;,以便了解哪些项目已被处理(使用集合)以及哪些项目需要处理(队列)。
    【解决方案2】:

    使用 Dequeue 代替 foreach 循环。每当底层容器更改时,大多数枚举器都会变得无效。 En-/Dequeue 是队列上的自然操作。否则你可以使用List&lt;T&gt;HashSet&lt;T&gt;

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

    要检查一个项目是否已经被处理,HashSet&lt;T&gt; 是一个快速的解决方案。在这些情况下,我通常使用 HashSet 和 Queue 的组合。这个解决方案的优点是它是 O(n),因为检查并添加到 HashSet 是 O(1)。您的原始代码是 O(n^2),因为 Contains 上的 Queue 是 O(n)。

    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();
          ...
        }  
    }
    

    【讨论】:

    • @Makara 添加了一个示例,我使用 Queue 来保存未处理的项目,并使用 HashSet 来避免重复。
    【解决方案3】:

    循环迭代通常会增加更多工作;只需将队列作为参数传递给方法并添加到它应该可以正常工作。

    问题是你应该使用 Dequeue:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 2010-10-31
      相关资源
      最近更新 更多