首页 >后端开发 >C++ >如何在C#中有效地将通用列表改组?

如何在C#中有效地将通用列表改组?

Mary-Kate Olsen
Mary-Kate Olsen原创
2025-02-03 07:58:131004浏览

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