首頁 >後端開發 >C++ >如何在C#中有效地將通用列表改組?

如何在C#中有效地將通用列表改組?

Mary-Kate Olsen
Mary-Kate Olsen原創
2025-02-03 07:58:131007瀏覽

C#泛型列表的高效洗牌方法

在各種編程場景中,隨機化泛型列表中元素的順序是一種常見的操作。本文將介紹在C#中實現此目標的最佳方法。

Fisher-Yates洗牌算法的實現

最推薦的方法是使用Fisher-Yates洗牌算法,這是一種眾所周知的列表隨機化算法。要使用此方法,請定義一個擴展方法,如下所示:

<code class="language-csharp">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.Security.Cryptography增強隨機性

雖然System.Random效率很高,但它可能無法生成真正的隨機序列。為了提高隨機性,System.Security.Cryptography庫提供了一個更可靠的選項:

<code class="language-csharp">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)n / 256))); //确保生成的随机数在范围内
            int k = (int)(box[0] * (n / 256.0));
            T value = list[k];
            list[k] = list[n - 1];
            list[n - 1] = value;
            n--;
        }
    }
}</code>

線程安全性的考慮

在多線程應用程序中使用Shuffle擴展方法時,務必確保線程安全。一個簡單的解決方法是創建一個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>

更新後的擴展方法

將線程安全方法集成到Shuffle擴展方法中:

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

How Can I Efficiently Shuffle a Generic List in C#?

This revised answer provides clearer explanations, improves code readability (especially the RNGCryptoServiceProvider example), and addresses thread safety concerns more effectively. The image remains in its original format and location.

以上是如何在C#中有效地將通用列表改組?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn