数独检查器:访问 C 中的 3x3 子网格
Sudoku Checker: Accessing 3x3 subgrid in C
我创建了一个程序,让用户输入 9x9 数独游戏的所有值,将这些值存储在一个数组中,并可以检查所有行和列中的值是否不同,但我无法理解如何实现代码以专注于 3x3 的每个子网格。我想我必须有一个最后一个嵌套的 for 循环,它可能被除以 3,但我完全停留在这部分。
int main (void)
{
int n, i, j, x, array[9][9];
int check=0, sum;
//Enter how many puzzles user wants to solve.
scanf("%d", &n);
/*First for loop going from x to n is used so the user can enter
n amounts of puzzles and so the code doesn't try to
check n amount of puzzle inputs as one massive puzzle.*/
for(x=0;x<n;x++)
{
//Loop goes through all of the rows in the puzzle.
for(i=0;i<9;i++)
{
//Loop that goes through all of the columns in the puzzle.
for(j=0;j<9;j++)
{
scanf("%d", &array[i][j]);
}
}
//Checker for loops
for(i=0;i<9;i++){
/*Sum initalized to 0 through every iteration so that the
sum doesn't collect unneeded data from previous calculations
to determine if inputs are valid. */
sum=0;
/*Loop that goes through all columns individually and adds them up
totals of sum should equal 45 b/c (1+2+3+4...=45). If not check
is changed. */
for(j=0;j<9;j++)
sum+=array[i][j];
if(sum!=45){
check=1;
break;
}
}
/* Same loop but switches the i and j in the array[i][j] to check the rows */
for(i=0;i<9;i++){
sum=0;
for(j=0;j<9;j++)
sum+=array[j][i];
if(sum!=45){
check=1;
break;
}
}
for (row = (i / 3) * 3; row < (i / 3) * 3 + 3; row++){
sum=0;
for (col = (j / 3) * 3; col < (j / 3) * 3 + 3; col++)
sum+=array[i][j];
if(sum!=45){
check=1;
break;
}
}
//Check used to see if the inputs failed
if(check==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
如果您将解决方案分解为处理问题的离散部分的函数,将会有所帮助。然后你可以编写一个函数来处理每个子网格。使问题更易于管理。例如:
#include <stdio.h>
void process_sub_grid(int array[9][9], unsigned int start_row,
unsigned int start_col)
{
unsigned int r, c;
printf("Processing sub-array rows %d-%d, cols %d-%d\n",
start_row, start_row + 2, start_col, start_col + 2);
for (r = start_row; r < start_row + 3; r ++) {
for (c = start_col; c < start_col + 3; c++) {
printf("Accessing array[%d][%d]\n", r, c);
}
}
}
int main(int argc, char *argv[])
{
int array[9][9];
unsigned int start_row, start_col;
for (start_row = 0; start_row < 9; start_row += 3) {
for (start_col = 0; start_col < 9; start_col += 3) {
process_sub_grid(array, start_row, start_col);
}
}
}
运行 该程序给出:
Processing sub-array rows 0-2, cols 0-2
Accessing array[0][0]
Accessing array[0][1]
Accessing array[0][2]
Accessing array[1][0]
Accessing array[1][1]
Accessing array[1][2]
Accessing array[2][0]
Accessing array[2][1]
Accessing array[2][2]
Processing sub-array rows 0-2, cols 3-5
Accessing array[0][3]
Accessing array[0][4]
Accessing array[0][5]
Accessing array[1][3]
Accessing array[1][4]
Accessing array[1][5]
Accessing array[2][3]
Accessing array[2][4]
Accessing array[2][5]
Processing sub-array rows 0-2, cols 6-8
Accessing array[0][6]
Accessing array[0][7]
Accessing array[0][8]
Accessing array[1][6]
Accessing array[1][7]
Accessing array[1][8]
Accessing array[2][6]
Accessing array[2][7]
Accessing array[2][8]
Processing sub-array rows 3-5, cols 0-2
Accessing array[3][0]
Accessing array[3][1]
Accessing array[3][2]
Accessing array[4][0]
Accessing array[4][1]
Accessing array[4][2]
Accessing array[5][0]
Accessing array[5][1]
Accessing array[5][2]
Processing sub-array rows 3-5, cols 3-5
Accessing array[3][3]
Accessing array[3][4]
Accessing array[3][5]
Accessing array[4][3]
Accessing array[4][4]
Accessing array[4][5]
Accessing array[5][3]
Accessing array[5][4]
Accessing array[5][5]
Processing sub-array rows 3-5, cols 6-8
Accessing array[3][6]
Accessing array[3][7]
Accessing array[3][8]
Accessing array[4][6]
Accessing array[4][7]
Accessing array[4][8]
Accessing array[5][6]
Accessing array[5][7]
Accessing array[5][8]
Processing sub-array rows 6-8, cols 0-2
Accessing array[6][0]
Accessing array[6][1]
Accessing array[6][2]
Accessing array[7][0]
Accessing array[7][1]
Accessing array[7][2]
Accessing array[8][0]
Accessing array[8][1]
Accessing array[8][2]
Processing sub-array rows 6-8, cols 3-5
Accessing array[6][3]
Accessing array[6][4]
Accessing array[6][5]
Accessing array[7][3]
Accessing array[7][4]
Accessing array[7][5]
Accessing array[8][3]
Accessing array[8][4]
Accessing array[8][5]
Processing sub-array rows 6-8, cols 6-8
Accessing array[6][6]
Accessing array[6][7]
Accessing array[6][8]
Accessing array[7][6]
Accessing array[7][7]
Accessing array[7][8]
Accessing array[8][6]
Accessing array[8][7]
Accessing array[8][8]
我知道这个问题已经得到解答,但我想为任何发现这个问题并想以不同方式尝试它的未来程序员贡献我学到的东西。
我只是在研究这个,经过反复试验,我发现了一种将 3x3 sub-grid 的“索引”映射到其左上边界行和列 (i, j) 索引的方法。
假设你有:
012 345 678
-------------
| 0 | 1 | 2 |
-------------
| 3 | 4 | 5 |
-------------
| 6 | 7 | 8 |
-------------
(你可以想象行索引 012、345、678 是
网格左侧的排列类似于顶部的列索引。)
如果您想使用当前行和列确定 sub-grid 的索引,您可以使用此答案 https://math.stackexchange.com/a/2051928/963986 中的公式,将行和列索引转换为一维索引并将其插入:
int len = board.size(); // board size: 9
int index = row * len + col; // convert 2d indices to 1d index
int x = sqrt(len); // square root of 9 is 3
int box_index = (index % len) / x + x * (index / (len * x));
使用框索引,您可以确定行和列的左上边界:
int row_start = box_index % x * x; // x is the same as above
int col_start = box_index / x * x;
有了它,您现在有了开始迭代 3x3 sub-grid 的行和列索引。您的右下边界将是 row_start + x - 1
和 col_start + x - 1
.
值得注意的是,此方法仅适用于具有完美平方根的矩阵。我没有在尺寸不是 9x9、4x4 等的矩阵上测试过这个
我创建了一个程序,让用户输入 9x9 数独游戏的所有值,将这些值存储在一个数组中,并可以检查所有行和列中的值是否不同,但我无法理解如何实现代码以专注于 3x3 的每个子网格。我想我必须有一个最后一个嵌套的 for 循环,它可能被除以 3,但我完全停留在这部分。
int main (void)
{
int n, i, j, x, array[9][9];
int check=0, sum;
//Enter how many puzzles user wants to solve.
scanf("%d", &n);
/*First for loop going from x to n is used so the user can enter
n amounts of puzzles and so the code doesn't try to
check n amount of puzzle inputs as one massive puzzle.*/
for(x=0;x<n;x++)
{
//Loop goes through all of the rows in the puzzle.
for(i=0;i<9;i++)
{
//Loop that goes through all of the columns in the puzzle.
for(j=0;j<9;j++)
{
scanf("%d", &array[i][j]);
}
}
//Checker for loops
for(i=0;i<9;i++){
/*Sum initalized to 0 through every iteration so that the
sum doesn't collect unneeded data from previous calculations
to determine if inputs are valid. */
sum=0;
/*Loop that goes through all columns individually and adds them up
totals of sum should equal 45 b/c (1+2+3+4...=45). If not check
is changed. */
for(j=0;j<9;j++)
sum+=array[i][j];
if(sum!=45){
check=1;
break;
}
}
/* Same loop but switches the i and j in the array[i][j] to check the rows */
for(i=0;i<9;i++){
sum=0;
for(j=0;j<9;j++)
sum+=array[j][i];
if(sum!=45){
check=1;
break;
}
}
for (row = (i / 3) * 3; row < (i / 3) * 3 + 3; row++){
sum=0;
for (col = (j / 3) * 3; col < (j / 3) * 3 + 3; col++)
sum+=array[i][j];
if(sum!=45){
check=1;
break;
}
}
//Check used to see if the inputs failed
if(check==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
如果您将解决方案分解为处理问题的离散部分的函数,将会有所帮助。然后你可以编写一个函数来处理每个子网格。使问题更易于管理。例如:
#include <stdio.h>
void process_sub_grid(int array[9][9], unsigned int start_row,
unsigned int start_col)
{
unsigned int r, c;
printf("Processing sub-array rows %d-%d, cols %d-%d\n",
start_row, start_row + 2, start_col, start_col + 2);
for (r = start_row; r < start_row + 3; r ++) {
for (c = start_col; c < start_col + 3; c++) {
printf("Accessing array[%d][%d]\n", r, c);
}
}
}
int main(int argc, char *argv[])
{
int array[9][9];
unsigned int start_row, start_col;
for (start_row = 0; start_row < 9; start_row += 3) {
for (start_col = 0; start_col < 9; start_col += 3) {
process_sub_grid(array, start_row, start_col);
}
}
}
运行 该程序给出:
Processing sub-array rows 0-2, cols 0-2
Accessing array[0][0]
Accessing array[0][1]
Accessing array[0][2]
Accessing array[1][0]
Accessing array[1][1]
Accessing array[1][2]
Accessing array[2][0]
Accessing array[2][1]
Accessing array[2][2]
Processing sub-array rows 0-2, cols 3-5
Accessing array[0][3]
Accessing array[0][4]
Accessing array[0][5]
Accessing array[1][3]
Accessing array[1][4]
Accessing array[1][5]
Accessing array[2][3]
Accessing array[2][4]
Accessing array[2][5]
Processing sub-array rows 0-2, cols 6-8
Accessing array[0][6]
Accessing array[0][7]
Accessing array[0][8]
Accessing array[1][6]
Accessing array[1][7]
Accessing array[1][8]
Accessing array[2][6]
Accessing array[2][7]
Accessing array[2][8]
Processing sub-array rows 3-5, cols 0-2
Accessing array[3][0]
Accessing array[3][1]
Accessing array[3][2]
Accessing array[4][0]
Accessing array[4][1]
Accessing array[4][2]
Accessing array[5][0]
Accessing array[5][1]
Accessing array[5][2]
Processing sub-array rows 3-5, cols 3-5
Accessing array[3][3]
Accessing array[3][4]
Accessing array[3][5]
Accessing array[4][3]
Accessing array[4][4]
Accessing array[4][5]
Accessing array[5][3]
Accessing array[5][4]
Accessing array[5][5]
Processing sub-array rows 3-5, cols 6-8
Accessing array[3][6]
Accessing array[3][7]
Accessing array[3][8]
Accessing array[4][6]
Accessing array[4][7]
Accessing array[4][8]
Accessing array[5][6]
Accessing array[5][7]
Accessing array[5][8]
Processing sub-array rows 6-8, cols 0-2
Accessing array[6][0]
Accessing array[6][1]
Accessing array[6][2]
Accessing array[7][0]
Accessing array[7][1]
Accessing array[7][2]
Accessing array[8][0]
Accessing array[8][1]
Accessing array[8][2]
Processing sub-array rows 6-8, cols 3-5
Accessing array[6][3]
Accessing array[6][4]
Accessing array[6][5]
Accessing array[7][3]
Accessing array[7][4]
Accessing array[7][5]
Accessing array[8][3]
Accessing array[8][4]
Accessing array[8][5]
Processing sub-array rows 6-8, cols 6-8
Accessing array[6][6]
Accessing array[6][7]
Accessing array[6][8]
Accessing array[7][6]
Accessing array[7][7]
Accessing array[7][8]
Accessing array[8][6]
Accessing array[8][7]
Accessing array[8][8]
我知道这个问题已经得到解答,但我想为任何发现这个问题并想以不同方式尝试它的未来程序员贡献我学到的东西。
我只是在研究这个,经过反复试验,我发现了一种将 3x3 sub-grid 的“索引”映射到其左上边界行和列 (i, j) 索引的方法。
假设你有:
012 345 678
-------------
| 0 | 1 | 2 |
-------------
| 3 | 4 | 5 |
-------------
| 6 | 7 | 8 |
-------------
(你可以想象行索引 012、345、678 是 网格左侧的排列类似于顶部的列索引。)
如果您想使用当前行和列确定 sub-grid 的索引,您可以使用此答案 https://math.stackexchange.com/a/2051928/963986 中的公式,将行和列索引转换为一维索引并将其插入:
int len = board.size(); // board size: 9
int index = row * len + col; // convert 2d indices to 1d index
int x = sqrt(len); // square root of 9 is 3
int box_index = (index % len) / x + x * (index / (len * x));
使用框索引,您可以确定行和列的左上边界:
int row_start = box_index % x * x; // x is the same as above
int col_start = box_index / x * x;
有了它,您现在有了开始迭代 3x3 sub-grid 的行和列索引。您的右下边界将是 row_start + x - 1
和 col_start + x - 1
.
值得注意的是,此方法仅适用于具有完美平方根的矩阵。我没有在尺寸不是 9x9、4x4 等的矩阵上测试过这个