C# 生成1到16之间的随机数

C# 生成1到16之间的随机数,c#,random,C#,Random,大家好,我有二维数组4*4。我必须用1到16的数字随机填写。每个数字只能使用一次,并且应使用1-16之间的所有数字。我已经编写了以下代码,但由于某种原因,我不知道数组中的某些项没有填充!! 谁能告诉我我做错了什么 public void generateRandState() { bool flag = false; Random rnd = new Random(); int temp ; for (int i =

大家好,我有二维数组4*4。我必须用1到16的数字随机填写。每个数字只能使用一次,并且应使用1-16之间的所有数字。我已经编写了以下代码,但由于某种原因,我不知道数组中的某些项没有填充!! 谁能告诉我我做错了什么

    public void generateRandState()
    {
        bool flag = false;
        Random rnd = new Random();
        int temp ;
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                temp = rnd.Next(1, 17);
                Console.WriteLine(temp);
                if (taken[temp] == false)
                {
                    state[i, j] = temp;
                    taken[temp] = true;
                }
                else // for repeated rands
                {
                    temp = rnd.Next(1, 17);
                    Console.WriteLine(temp);
                    while (!flag)
                    {
                        if (taken[temp] == false)
                        {
                            flag = true;
                            break;
                        }
                        else
                            temp = rnd.Next(1, 17);
                        Console.WriteLine(temp);
                    }
                    if (taken[temp] == false)
                    {
                        state[i, j] = temp;
                        taken[temp] = true;

                    }

                }

            }
        }
    }
public void generateRandState()
{
布尔标志=假;
随机rnd=新随机();
内部温度;
对于(int i=0;i<4;i++)
{
对于(int j=0;j<4;j++)
{
温度=下一个(1,17)的rnd;
控制台写入线(临时);
如果(取[temp]==false)
{
状态[i,j]=温度;
取[temp]=真;
}
else//用于重复rands
{
温度=下一个(1,17)的rnd;
控制台写入线(临时);
while(!flag)
{
如果(取[temp]==false)
{
flag=true;
打破
}
其他的
温度=下一个(1,17)的rnd;
控制台写入线(临时);
}
如果(取[temp]==false)
{
状态[i,j]=温度;
取[temp]=真;
}
}
}
}
}
每个数字只能使用一次,并且应使用1-16之间的所有数字

这称为随机洗牌。您可以使用来构建它

提供它的代码

static Random _random = new Random();
public static void Shuffle<T>(T[] array) {
var random = _random;
for (int i = array.Length; i > 1; i--) {
    int j = random.Next(i); // 0 <= j <= i-1
    T tmp = array[j];
    array[j] = array[i - 1];
    array[i - 1] = tmp;
}
}
static Random\u Random=new Random();
公共静态无效洗牌(T[]数组){
var random=_random;
对于(int i=array.Length;i>1;i--){
int j=random.Next(i);//0用
while(true)
替换
while(!flag)
break
将使您退出
while
语句。
flag
变量完全不需要

你的算法效率很低。正如dasblinkenlight指出的,有更好的方法来完成你正在做的事情


您还应该知道,如果您多次调用
generateRandState
,则需要清除
take

您可能需要在
语句之前将
标志设置为false,而
语句通过学习使用调试器并逐步执行代码,您将学到更多。@leetylor如果我将其设置为true它会多次使用同一个数字,这是不允许的。不,你的while循环第一次运行,之后它就再也不会运行了。我有一个问题,如果我多次调用这个函数,它每次都会产生相同的输出吗???@Alaa根据你的需要,你可以双向使用。因为
Random
实际上是一个伪随机数m生成器,您可以通过提供相同的种子值使其再次生成相同的序列。如果您不想看到相同的排列,请使用不同的种子为随机数生成器种子。您仍然可以通过偶发事件获得相同的排列,因为它们的数量有限,但发生的概率非常低。@Alaa一般来说,是的,因为你的代码可能需要一段时间才能发现
take[]
数组中的几个非take点。当你有16个项目时,这并不重要,因为我们讨论的是微秒级的差异。如果你冒险进入一个25x25的网格,洗牌速度会明显加快。