如何用唯一的随机数填充二维数组

时间:2016-11-05 18:27:41

标签: c#

如何用唯一的随机数(行/列中的不同数字)填充二维数组?

我已经完成了1维数组:

class Program
{
    static void Main(string[] args)
    {
        Random r = new Random();

        int[] x = new int[10];

        for(int i = 0; i < x.Length; i++)
        {
            x[i] = r.Next(9);

            for(int j = 0; j < i; j++)
            {
                if(x[i] == x[j])
                {
                    i--;
                    break;
                }
            }
        }

        for(int i = 0; i < x.Length; i++)
        {
            Console.WriteLine(x[i]);
        }

        Console.ReadKey();
    }
}

3 个答案:

答案 0 :(得分:3)

由于您不想要任何重复项,因此重复使用Random,直到您拥有其中一个不是最好的方法。从理论上讲,如果随机数发生器在早期没有提供所需的值,那么像这样的算法可以运行非常长时间。

既然你知道你想要什么值,但是想要它们是随机顺序的,那么shuffle算法通常是更好的方法。 一个shuffle算法允许你生成一个所需值的数组,然后将它们随机播放以便以随机顺序获取它们。

使其适用于多维数组的最简单方法可能是首先在一维数组中包含所有所需的值,然后将其混洗,然后将数组转换为多维数组。 但是,it is possible可以推广一个混洗算法来处理多维数组。

参考答案中提供了代码的外观示例。

答案 1 :(得分:0)

这听起来有点像家庭作业。这里的想法是将一个固定范围(在你的情况下,10x10)的整数混合成一个二维整数数组,例如int[10,10]

using System;
using System.Linq;
using System.Collections;

class MainClass {

  public static void Main (string[] args) {
    // table dimension (assumes a square)
    var dim = 10;
    var table = new int?[dim, dim];

    // 100 integers: 0..99
    var queue = new Queue(Enumerable.Range(0, dim * dim).ToList<int>());
    var rng = new Random();


    int x = dim / 2, y = dim / 2;

    // Acceptable shuffle? As long as the queue has anything in it, try to place the next number
    while(queue.Count > 0) {
        x = rng.Next(dim);  // still using random, not great! :(
        y = rng.Next(dim);

        if(table[x,y] == null)
            table[x,y] = (int)queue.Dequeue();
    }

    // print output so I know I'm not crazy
    for(var i = 0; i < dim; i++) {
        Console.Write("Row {0}: [", i);
        for(var j = 0; j < dim; j++) {
            Console.Write("{0,4}", table[i,j]);
        }
        Console.WriteLine("]");
    }
  }
}

输出:

Mono C# compiler version 4.0.4.0

Row 0: [  55  45  38  23  88  46   7  89   0  94]
Row 1: [   2  92  43  51  58  67  82  90  79  17]
Row 2: [  29  64  16   8  50  14   1  25  26  73]
Row 3: [  97  37  13  20   4  75  98  80  48  12]
Row 4: [  33  27  42  74  95  35  57  53  96  60]
Row 5: [  59  86  76  40   6  11  77  49  93  61]
Row 6: [   5  72   9  91  68  30  39  69  99  21]
Row 7: [  52  31  28  34   3  81  18  62  10  71]
Row 8: [  66  24  44  54  56  85  84  22  47  63]
Row 9: [  65  36  83  41  15  19  87  78  70  32]

答案 2 :(得分:0)

这是我实施MAV答案的镜头:

private Random random = new Random();

private void Shuffle(ref int[] array)
{
    int r, temp;
    for (int i = array.Length - 1; i >= 0; i--)
    {
        r = random.Next(i + 1);
        temp = array[r];
        array[r] = array[i];
        array[i] = temp;
    }
}

public int[,] GetUniqueArray()
{
    int[,] array = new int[10,10];

    int[] temp = Enumerable.Range(0, 100).ToArray();
    Shuffle(ref temp);

    for (int i = 0; i < temp.Length; i++)
    {
        array[i / array.GetLength(0), i % array.GetLength(1)] = temp[i];
    }

    return array;
}

就像他说的那样,强制数组的内容随机而且唯一可能会导致问题,具体取决于数组的大小。如果遇到产生大量冲突的情况,那么它会导致程序慢慢爬行,同时为单个数组索引生成数百个随机数,只是盲目地寻找尚未使用的数据

这种方法更好,因为你开始使用已经填充了唯一数字的所需大小的数组,从那时起你只需随机化它们的顺序。通过恒定的运行时间和更少的问题,您可以获得所需的结果。