0

我有一个列表,我想每次都按随机顺序排序。

我遇到了几种方法:

  1. list = list.OrderBy(x => Guid.NewGuid()).ToList();
    
  2. var rnd = new Random();
    myList = myList.OrderBy(x => rnd.Next()).ToList();
    
  3. static Random random = new Random();
    
    public static IEnumerable<T> RandomPermutation<T>(IEnumerable<T> sequence)
    {
        T[] retArray = sequence.ToArray();
    
        for (int i = 0; i < retArray.Length - 1; i += 1)
        {
            int swapIndex = random.Next(i + 1, retArray.Length);
            T temp = retArray[i];
            retArray[i] = retArray[swapIndex];
            retArray[swapIndex] = temp;
        }
    
        return retArray;
    }
    

明明1和3的代码量差别很大,但是有什么好处吗?

4

1 回答 1

7

第一个只是坏事。 GUID 是唯一的,但它们不一定是随机的。 虽然某些 GUID 实现可能依赖于随机性,但另一些则不会。这里的结果是在一台机器上运行的完全相同的程序可以工作,而在另一台机器上则不能。这真的很糟糕,因为这意味着你将测试你的程序,它会很好地出来,你会发布它,然后事情就会崩溃。

第三个是非常标准的洗牌算法。在解决这个问题时,我通常会使用它。

第二个选项会起作用,但它的效率明显低于第三个选项。排序的渐近复杂度高于您在此处显示的第三种算法(O(n*log(n)) 而不是 O(n))。

如果您每次想要使用它时都必须编写代码,那么该方法中的价值可能是 2 行而不是 12 行,但是当您只需要编写一次并在任何时候简单地引用该通用 shuffle 方法时需要改组一个序列,您可以使用语义上正确且更有效的代码来证明其合理性。(毕竟它没有那么长或复杂。)

于 2013-05-17T18:34:04.600 回答