随机列出

随机列出,第1张

随机列出

随机播放任何

(I)List
基于该扩展方法费雪耶茨洗牌:

private static Random rng = new Random();public static void Shuffle<T>(this IList<T> list)  {      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();

上面的代码使用备受批评的System.Random方法来选择交换候选。它速度很快,但不如应有的随机。如果您需要更好的随机性,请使用System.Security.Cryptography中的随机数生成器,如下所示:

using System.Security.Cryptography;...public static void Shuffle<T>(this IList<T> list){    RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();    int n = list.Count;    while (n > 1)    {        byte[] box = new byte[1];        do provider.GetBytes(box);        while (!(box[0] < n * (Byte.MaxValue / n)));        int k = (box[0] % n);        n--;        T value = list[k];        list[k] = list[n];        list[n] = value;    }}

在此博客(WayBack
Machine)上可以进行简单的比较。

编辑:自从几年前写下这个答案以来,许多人向我发表评论或写信给我,指出我的比较中的一个愚蠢的缺陷。他们当然是对的。如果System.Random按预期方式使用,则没有任何问题。在上面的第一个示例中,我在Shuffle方法内部实例化了rng变量,该变量询问是否要重复调用该方法。以下是一个固定的完整示例,该示例基于今天从@weston收到的关于SO的非常有用的评论。

Program.cs:

using System;using System.Collections.Generic;using System.Threading;namespace SimpleLottery{  class Program  {    private static void Main(string[] args)    {      var numbers = new List<int>(Enumerable.Range(1, 75));      numbers.Shuffle();      Console.WriteLine("The winning numbers are: {0}", string.Join(",  ", numbers.GetRange(0, 5)));    }  }  public static class ThreadSafeRandom  {      [ThreadStatic] private static Random Local;      public static Random ThisThreadsRandom      {          get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }      }  }  static class MyExtensions  {    public static void Shuffle<T>(this IList<T> list)    {      int n = list.Count;      while (n > 1)      {        n--;        int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);        T value = list[k];        list[k] = list[n];        list[n] = value;      }    }  }}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5564558.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-14
下一篇 2022-12-14

发表评论

登录后才能评论

评论列表(0条)

保存