2013-05-13 154 views
1

我需要将一堆项目添加到数据结构中,然后以随机顺序访问其中的所有项目。我怎样才能做到这一点?我可以用什么数据结构随机访问它的内容?

更具体地说,我目前将URL添加到一个List<string>对象。它们的添加方式使得相邻的URL可能位于同一台服务器上。当我使用Parallel.ForEach语句访问List时,它只是按照我添加它们的顺序返回项目。通常这没问题,但是当我并行发出Web请求时,这往往会压倒一些服务器并导致超时。当我在对象上运行一个Parallel.ForEach语句时(即不是按照我添加它们的顺序),我可以使用哪种数据结构将以更随机的方式返回项目?

+3

也许只是[shuffle](http://stackoverflow.com/questions/273313/randomize-a-listt-in-c-sharp)一旦你添加了所有物品的列表? – Blorgbeard 2013-05-13 23:33:08

+5

真的是你想要的随机数?或者你想有一个服务器列表,每个服务器都有一个URL列表,然后在服务器上运行Parallel.ForEach,但不在URL上运行? – 2013-05-13 23:34:41

+1

我编辑了你的标题。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2013-05-13 23:34:51

回答

1

ORIGINAL SOLUTION

Fisher–Yates shuffle

public static void Shuffle<T>(this IList<T> list) 
{ 
    Random rng = new Random(); 
    int n = list.Count; 
    while (n > 1) { 
     n--; 
     int k = rng.Next(n + 1); 
     T value = list[k]; 
     list[k] = list[n]; 
     list[n] = value; 
    } 
} 

List<Product> products = GetProducts(); 
products.Shuffle(); 
+9

老兄,如果你打算从另一个答案逐字复制代码,*至少* [link to it](http://stackoverflow.com/a/1262619/369)! – Blorgbeard 2013-05-13 23:40:07

1

我认为洗牌是一个更好的答案,但回答您的具体问题将是一个Hashtable。您将添加字符串url作为键,值为null。 Keys属性将按照它们恰好放置在散列表中的顺序返回字符串,这将是相当随机的,因为字符串的hashcode和冲突处理将导致顺序与字符串的排序顺序没有很好的关联价值本身。

Dictionary和HashSet的工作方式不一样。他们的内部实现最终会按照添加的顺序返回项目。

虽然这就是Hashtable实际上的工作方式,但您会依赖内部实现细节,这有潜在的风险。这就是为什么我只喜欢洗牌。

+0

那么,HashSet是由LinkedHashSet实现的?这很好理解,而且似乎也不是文档的一部分。 – ILMTitan 2013-05-14 00:18:40

+0

@ILMTitan - Dictionary&HashSet是使用封闭寻址实现的 - 指向单个链表的散列桶。所有链表都在一个数组中,并且该数组的元素按照它们所需的顺序发送。枚举数枚举该数组。所以最终的结果是你可以按照你添加的顺序重新获得东西(假设你没有删除任何东西)。 – hatchet 2013-05-14 00:40:09

相关问题