2011-05-02 55 views
0

可能重複:
Most efficient way to randomly 「sort」 (Shuffle) a list of integers in C#隨機列表的副本<T>

如何有效地創建List<T>隨機副本?

List<string> myList = new List<string>(); 
myList.Add("A"); 
myList.Add("B"); 
myList.Add("C"); 

// Now an extension method or a function which returns a random arrangement of myList: 

List<string> GetRandomList() 
{ 
    // List<string> result = new List<string>(); 
    // Random rnd = new Random(); 
    // Inside a loop 
    // result.Add(myList[rnd.Next(1, myList.Count)]); 
} 

擴展方法woud是public static List<T> Shuffle(List<T> this)

+0

http://stackoverflow.com/questions/2459264/why-is-fisher-yates-the-most-useful-shuffling-algorithm – 2011-05-02 00:12:51

+0

http://stackoverflow.com/questions/1287567/c-is-using -random-and-orderby-a-good-shuffle-algorithm – 2011-05-02 00:13:09

+0

http://stackoverflow.com/questions/3343797/is-this-c-implementation-of-fisher-yates-shuffle-correct – 2011-05-02 00:13:53

回答

4

你正在尋找一個洗牌,有各種實現在那裏,通常Fisher-Yates shuffle

下面從here採取了通用實現:

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

注意,這個重新排序列表到位,它很容易重構它返回一個新的列表,如果這就是你想要做什麼。

+0

+1:感謝 – Xaqron 2011-05-02 00:09:13

+0

這個詞倒是會改變列表本身,而不是返回一個新的混洗列表。 – Xaqron 2011-05-02 00:28:47

0
public List<T> Random<T>(this IEnumerable<T> collection) 
{ 
    return collection.OrderBy(i => Guid.NewGuid()).ToList(); 
} 

感謝Jeff Atwood for this solution

+0

這隻會調用集合中每個項目一次的委託,還是多次?假設我們想要對列表{1,2,3}進行混洗,並且OrderBy實現決定比較'1'和'2',然後比較'1'和'3'。它會調用委託,它將調用'NewGuid',但是當它想要將兩個不同的數字比較爲1時,它會只調用一次還是多次調用'NewGuid'?如果它多次調用,那麼這不會產生好的洗牌,並且最終的順序在很大程度上取決於OrderBy的實現。 – 2011-05-02 00:55:14

+0

它會多次調用它。 – 2011-05-02 01:12:28

+1

請參閱http://www.robweir.com/blog/2010/02/microsoft-random-browser-ballot.html,瞭解有關以不良方式進行混洗的結果的有趣分析。在這種情況下,比較函數('int Compare(object a,object b)')返回一個隨機數1或-1。由於排序的實施方式,所產生的排序不是隨機的,而是因排序實施而有所不同。 – 2011-05-02 04:43:31