高效隨機排序C#列表
在C#中,對泛型列表進行隨機排序是軟件開發中常見的任務。例如,在彩票應用程序中,您可能需要對有限的數字集合進行隨機排序。
最佳實踐:
在C#中,隨機排序列表最有效的方法是使用基於Fisher-Yates洗牌算法的擴展方法。下面提供的此方法確保高效且真正隨機地洗牌列表元素:
<code class="language-csharp">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; } }</code>
使用方法:
使用此擴展方法很簡單。考慮以下示例:
<code class="language-csharp">List<Product> products = GetProducts(); products.Shuffle();</code>
隨機數生成器的選擇:
雖然上面的代碼使用System.Random
方法,但必須承認其在隨機性方面的潛在局限性。如果您的應用程序需要更高質量的隨機性,您可以利用System.Security.Cryptography
中提供的隨機數生成器,如下所示:
<code class="language-csharp">using System.Security.Cryptography; ... public static void Shuffle<T>(this IList<T> list) { using (RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider()) { int n = list.Count; while (n > 1) { byte[] box = new byte[1]; do provider.GetBytes(box); while (!(box[0] < (byte)((double)byte.MaxValue * (double)n / (double)uint.MaxValue))); int k = (int)(box[0] / ((double)byte.MaxValue / n)); T value = list[k]; list[k] = list[n - 1]; list[n - 1] = value; } } }</code>
線程安全:
為了確保線程安全的隨機化,必須考慮以下修改後的擴展方法:
<code class="language-csharp">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; } }</code>
其中ThreadSafeRandom
定義為:
<code class="language-csharp">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))); } } }</code>
通過這些方法,您可以根據您的需求選擇最合適的隨機排序方法。 請注意using
語句在使用RNGCryptoServiceProvider
時的重要性,以確保正確釋放資源。
以上是如何在C#中有效地列出列表?的詳細內容。更多資訊請關注PHP中文網其他相關文章!