C# 随机生成一个唯一的数字网格

C# 随机生成一个唯一的数字网格,c#,random,C#,Random,我有一个2D整数数组,5x5,我制作了一个解决方案,在每个数组单元格中随机生成数字1-5: public int[,] generateGrid() { int seed = DateTime.Now.Second; // generate seed Random rand = new Random(seed); // initialise random number with seed int[,] grid = new int[_gridSize, _gridSiz

我有一个2D整数数组,5x5,我制作了一个解决方案,在每个数组单元格中随机生成数字1-5:

public int[,] generateGrid()
{
    int seed = DateTime.Now.Second; // generate seed
    Random rand = new Random(seed); // initialise random number with seed

    int[,] grid = new int[_gridSize, _gridSize]; // create 2D array for grid

    for (int i = 0; i < _gridSize; i++) // loop through rows
    {
        for (int j = 0; j < _gridSize; j++) // loop throug columns
        {
            int value = 0; // initialise the value to be entered into cell

            while (value == 0) // while value is invalid ( "0" ) keep generating new number
            {
                value = rand.Next() % _gridSize + 1; // generate value from 0 - gridsize
                grid[i, j] = value; // input value. Note: if value = 0, the loop will regenerate a new value
            }

        }
    }
    return grid; 
}
public int[,]generateGrid()
{
int seed=DateTime.Now.Second;//生成种子
Random rand=新随机数(种子);//使用种子初始化随机数
int[,]grid=new int[_gridSize,_gridSize];//为网格创建二维数组
for(int i=0;i<\u gridSize;i++)//循环行
{
for(int j=0;j<\u gridSize;j++)//循环通过列
{
int value=0;//初始化要输入到单元格中的值
while(value==0)//值无效时(“0”)继续生成新的数字
{
value=rand.Next()%\u gridSize+1;//从0生成值-gridSize
grid[i,j]=value;//输入值。注意:如果value=0,循环将重新生成一个新值
}
}
}
返回网格;
}
现在这个代码完成了它的工作。(不确定效率——任何关于效率的额外建议都会有帮助。)

但我的问题是,每一列和每一行只能包含一次数字1-5!(更像是数独)我不知道该怎么做(或者最好的方法)

我的第一个想法是制作一个堆栈,推送堆栈中每行创建的所有值,然后检查该行是否已经包含该值。如果有,生成一个新值,再次检查等。 但是迭代堆栈是一个坏主意,同样,这对于检查行是有好处的,但是当涉及到检查列的唯一性时,它变得有点困难


因此,基本上,我如何使所有行和列都是唯一的,但仍然能够每次随机生成。做这件事最好的方法是什么?

我想你可能需要像解数独一样做这件事。换句话说,最初每个单元格都可以包含5个值中的任意一个:因此可以随机设置第一个单元格,不受任何限制。然后设置下一个单元格:现在有一个限制,它不能有第一个单元格的值(它在同一行中),因此您可能需要执行几次操作才能获得有效的数字

只需沿着每一行和每一列继续工作,始终检查该行上已设置的值的左侧(下列索引),并检查该列上已设置的值的上方(下行索引)。如果您试图将单元格设置为已在此行或列上使用的值,请重试


如果需要使用不同大小的网格,这应该是可扩展的。如果有必要,我将留给您如何优化它(提示:设置最后一个单元格可能会比任何其他单元格花费更长的时间,即使它只有一个可能的值)。

我想您可能需要像解数独一样来做这件事。换句话说,最初每个单元格都可以包含5个值中的任意一个:因此可以随机设置第一个单元格,不受任何限制。然后设置下一个单元格:现在有一个限制,它不能有第一个单元格的值(它在同一行中),因此您可能需要执行几次操作才能获得有效的数字

只需沿着每一行和每一列继续工作,始终检查该行上已设置的值的左侧(下列索引),并检查该列上已设置的值的上方(下行索引)。如果您试图将单元格设置为已在此行或列上使用的值,请重试


如果需要使用不同大小的网格,这应该是可扩展的。如果有必要,我将留给您如何优化它(提示:设置最后一个单元格可能会比任何其他单元格花费更长的时间,即使它只有一个可能的值)。

我认为您不需要关心如此小的网格中的效率(即使在更大的网格中也不需要)


最简单的解决方案是检查当前行和列中您将要写入该单元格的值,只需在网格上进行迭代。

我认为您不需要关心这样一个小网格中的效率(即使在更大的网格中也不需要)


最简单的解决方案是,通过简单地在网格上迭代,检查当前行和列中您将要写入该单元格的值。

我找到了一个解决方案,我愿意为任何其他在这篇文章中寻找答案的人发布。要生成唯一的数字网格nxn(尽管我只测试了5x5), 下面的代码应该可以做到这一点:

//下面是C语言#

public int[,]generateGrid()//可能的更新::重置网格行时,请记住前面的顺序以避免两次相同的冲突
{
Random rand=新的Random();
ArrayList availableColumnNumbers=新ArrayList();
ArrayList AvailableRownNumber=新ArrayList();
ArrayList AvailableEnumbers=新的ArrayList();
int[,]grid=新int[_gridSize,_gridSize];
availableColumnNumbers=resetArrayList();//创建一个包含数字1-网格大小的列表
availableRowNumbers=resetArrayList();//创建一个包含数字1-网格大小的列表
for(int row=0;row<\u gridSize;row++)//循环行
{
for(int column=0;column<\u gridSize;column++)//循环遍历列
{
if(row==0)//如果第一行
{
int position=rand.Next(availableRowNumbers.Count);//生成一个随机位置
网格[row,column]=(int)AvailableRownNumber[position];//放置可用的行号
AvailableRownNumber.RemoveAt(位置);//更新可用的行号
}
else//要填充的行具有约束。请在考虑约束的情况下进行填充
{
//更新可用列号,找出列中已有的值,并生成唯一可用的值
availableColumnNumbers=getAvailableColumnNumbers(网格、列);
public int[,] generateGrid() // POSSIBLE UPDATE:: WHEN RESETING GRID ROW, REMEMBER PREVIOUS ORDER TO AVOID SAME COMFLICTION TWICE
{
    Random rand = new Random();
    ArrayList availableColumnNumbers = new ArrayList();
    ArrayList availableRowNumbers = new ArrayList();
    ArrayList availableNumbers = new ArrayList();
    int[,] grid = new int[_gridSize, _gridSize];

    availableColumnNumbers = resetArrayList(); // create a list that holds the numbers 1 - Grid Size
    availableRowNumbers = resetArrayList(); // create a list that holds the numbers 1 - Grid Size

    for (int row = 0; row < _gridSize; row++) // loop through rows
    {
        for (int column = 0; column < _gridSize; column++) // loop through columns
        {
            if (row == 0) // if row to be filled if the first row
            {
                int position = rand.Next(availableRowNumbers.Count); // Generate a random position
                grid[row, column] = (int)availableRowNumbers[position]; // place available row numbers
                availableRowNumbers.RemoveAt(position); // update available row numbers
            }
            else // row to be filled has constraints. Fill in, taking constraints into consideration
            {
                // update available column number, finds out what values are already in the column, and generates the only available values 
                availableColumnNumbers = getAvailableColumnNumbers(grid, column);
                // combine available Rows and Columns to get a list of available numbers for that cell
                availableNumbers = getSimilarNumbers(availableRowNumbers, availableColumnNumbers);

                if (availableNumbers.Count != 0) // if there are available numbers to place,
                {
                    int position = rand.Next(availableNumbers.Count);
                    grid[row, column] = (int)availableNumbers[position]; // place available number
                    availableRowNumbers.Remove((int)availableNumbers[position]); // update available row numbers
                }
                else // Confliction: There are no available numbers (restart entire row)
                {
                    grid = resetRow(grid, row); // reset the entire row where confliction occured
                    column = -1; // start again at begining of column
                    availableRowNumbers = resetArrayList(); // reset Array List
                }
            }
        }
        availableRowNumbers = resetArrayList();// reset available row array
    }
    return grid;