C 语言 - 如何在没有任何输入的情况下用 9 个 3x3 矩阵制作一个类似数独的棋盘

C language - How to make a sudoku like board with 9 pieces of 3x3 matrix, without any input

提问人:Misael Lim 提问时间:11/7/2023 最后编辑:UpAndAdamMisael Lim 更新时间:11/8/2023 访问量:81

问:

如何使数独板像数字生成器一样,有一些问题:
- 在一行/一列中,有从 1 到 9 的随机非重复数字?

这是我的源代码

#include <stdio.h>
#include <stdlib.h>

int main()
{
  int matrix [9][3][3];

  srand(time(NULL));

  mengisi_Matrix(matrix);

  tampilkan_Matrix(matrix);

  return 0;
}

void mengisi_Matrix(int matrix [9][3][3])
{
  for (int i = 1; i < 10; i++)
  {
    for (int j = 1; j < 4; j++)
    {
      for (int k = 1; k < 4; k++)
      {
        matrix[i][j][k] = (rand() % 9) + 1;
      }
    }
  }
}

void tampilkan_Matrix(int matrix [9][3][3])
{
  for (int i = 1; i < 10; i++)
  {
    printf("| ");

    for (int j = 1; j < 4; j++)
    {
      for (int k = 1; k < 4; k++) 
      {
        printf("%d ", matrix[i][j][k]);
      }

      printf("| ");

    }

    printf("\n");
    
    if (i % 3 == 0)
    {
      printf("- - - - + - - - + - - - - \n");
    }
  }
} 

我尝试使用 srand() 通过一个接一个的随机数填充一行。

但是在将其输入到 array[1][1][2] 之前,我想将随机生成的数字与同一行/列中的所有数组进行比较,如果已经存在该数字,它将生成新的随机数,依此类推,直到所有数组[9][3][3]填满。

我已经尝试了一堆我自己的逻辑,并试图询问 AI,但仍然没有解决方案,总是存在不需要的和非逻辑(对我来说)问题/错误/警告,例如隐式声明或冲突类型。希望你们比我更专业和专家的人能帮助我解决这个问题。

数组 C 比较 数独

评论

1赞 Lundin 11/7/2023
提示:与其使用 rand() 生成实际数字,不如创建一个数组。然后获取此数组的索引。如果为 false,则用作您的数字并设置否则,如果为 true(已取),则将索引增加 1 并检查数组中的下一项,继续前进,直到找到未取项,并通过达到索引 8 从 0 重新开始。bool taken[9] = {false}rand()%9index+1taken[index]=true;
0赞 Lundin 11/7/2023
至于如何生成适合已生成板的其余部分的数字,嗯,这是一个很大的话题,对 SO 来说可能太宽泛了。
0赞 Tom Karzes 11/7/2023
你们的指数都偏离了1。如果声明一个数组 ,则有效索引是通过 ,而不是通过 。所以你在这里有很多未定义的行为。这是发布代码的最大问题。在尝试修复其他细节之前修复该问题。a[N]0N-11N

答:

1赞 ikegami 11/7/2023 #1

您可以使用费舍尔-耶茨洗牌

void swap_ints( int *i, int *j ) {
   int tmp = *i;
   *i = *j;
   *j = tmp;
}

// An `int` in [0,n).
int rand_int( n ) {
   return rand() % n;
}

void shuffle( size_t n, int *a ) {
   while ( n-- )
      swap_ints( &a[ n ], &a[ rand_int( n + 1 ) ] );
}

例如

#define NUM_ELEMENTS( a ) ( sizeof( a ) / sizeof( *a ) )

int row[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

shuffle( NUM_ELEMENTS( row ), row );
|-----------------------------------|  Unused

     Pick one of the unused and move to end.
              +-------------------+
              |                   |
+---+---+---+-|-+---+---+---+---+-v-+
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
+---+---+---+-^-+---+---+---+---+-|-+
              |                   |
              +-------------------+
         Bump old value into unused pool.

|-------------------------------|  Unused

+---+-|-+---+---+---+---+---+-v-+ ---+
| 1 | 2 | 3 | 9 | 5 | 6 | 7 | 8 |  4 |
+---+-^-+---+---+---+---+---+-|-+ ---+

|---------------------------|  Unused

+---+---+---+---+---+---+-|-+ ---+---+  Not moving
| 1 | 8 | 3 | 9 | 5 | 6 | 7 |  2 | 4 |  is possible.
+---+---+---+---+---+---+-^-+ ---+---+  That's fine.

+---+---+---+-|-+---+-v-+ ---+---+---+  Same for
| 1 | 8 | 3 | 6 | 5 | 9 |  7 | 2 | 4 |  moving more
+---+---+---+-^-+---+-|-+ ---+---+---+  than once.

...

+---+---+---+---+---+---+---+---+---+
| 6 | 8 | 1 | 5 | 3 | 9 | 7 | 2 | 4 |
+---+---+---+---+---+---+---+---+---+

每当您为一个职位选择一个号码时,每个可用选项都有相同的选择变化。这意味着这是一个公平的算法(给定 的公平实现)。rand_int

评论

0赞 ikegami 11/8/2023
@Tom Karzes,固定