如何在 C# 中使用 Random class 随机排列数组

How to use Random class to shuffle array in C#

各位。所以我今天想练习 C#,但我一直在弄清楚如何使用 Random class 来简单地随机排列数组

例如这样:

using System;
                    
    public class Program
    {
        public static void Main()
        {
            int[] arr = {1,2,3,4,5};
        
            Random rand = new Random();
        
            for(int i =0; i < arr.Length; i++){
                int shuffle = rand.Next(arr[i]);
                Console.WriteLine(arr[shuffle]);
            }
            
        }
    }

如您所见,我尝试将此 int shuffle = rand.Next(arr[i]); 用作洗牌器,但是 我猜它只是重复了 array.I 中的一些元素 我对此还是一窍不通,在此先感谢您的回复。

最简单的方法是每次取两个随机数(例如a,b)。然后交换 arr[a] 和 arr[b]。它的质量取决于你交换元素的次数。

有一些解决方案,但我用它来创建一个随机数组并根据它进行排序

static class Program
{
    static void Main(string[] args)
    {
        var array = new[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        Shuffle(ref array);

        foreach (var item in array)
        {
            Console.WriteLine(item);
        }
        // Fri
        // Wed
        // Sat
        // Thu
        // Mon
        // Sun
        // Tue

    }

    static readonly Random rng = new Random();

    public static void Shuffle<T>(ref T[] array)
    {
        double[] key = new double[array.Length];
        for (int i = 0; i < key.Length; i++)
        {
            key[i] = rng.NextDouble();
        }

        Array.Sort(key, array);
    }
}

另一种方法是使用以下 1 行 LINQ 语句

    static void Main(string[] args)
    {
        var array = new[] { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };

        var result = array.OrderBy((item) => rng.NextDouble()).ToArray();

     }

这种类型的改组将需要 seeding the Randomn class 到数组的大小。对于 for 循环中的每次传递,它会将当前数字与数组中的随机其他数字交换。

这是随机播放的示例:

int[] arr = {1,2,3,4,5};

Random rand = new Random();

for(int i = 0; i < arr.Length; i++){
  int shuffle = rand.Next(arr.Length);
  int n = arr[i];
  arr.SetValue(arr[shuffle], i);
  arr.SetValue(n, shuffle);
}

Console.Write('[' + arr[0].ToString());
for(int i = 1; i < arr.Length; i++){
  Console.Write("," + arr[i]);
}
Console.Write("]");

您可以尝试实现 Fisher-Yates 改组算法:https://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle

    Random random = new Random();

    ...

    for (int i = 0; i < array.Length - 1; ++i) 
    {
        int r = random.Next(i, array.Length);
        (array[r], array[i]) = (array[i], array[r]);
    }

我建议为此提取一个方法

// Easiest, but not thread safe
private static Random random = new Random();

private static void Shuffle<T>(T[] array) 
{
    if (array is null)
        throw new ArgumentNullException(nameof(array));
    
    for (int i = 0; i < array.Length - 1; ++i) 
    {
        int r = random.Next(i, array.Length);
        (array[r], array[i]) = (array[i], array[r]);
    }
}   

您可以从 Main:

调用它
Shuffle(array);

你可以fiddle算法。