请求协助:将C语言数独程序中所有for循环转为while循环
修复数独求解代码中for转while的问题
我帮你找出了修改后代码里的几个关键错误,这些问题导致程序无法正常运行,咱们逐个分析并修复:
1. print_sudoku 函数的索引越界问题
你在while循环里先执行了i++和j++,导致直接跳过了索引0的元素,而且当i到8时,i++后变成9,访问matrix[9][j]就会越界。正确的逻辑应该是先执行循环体,再递增计数器:
void print_sudoku() { int i = 0; int j; while(i < SIZE) { j = 0; while(j < SIZE) { printf("%d\t", matrix[i][j]); j++; // 先输出再递增 } printf("\n\n"); i++; // 先处理完一行再递增行号 } }
2. is_safe 函数的逻辑错误
这个函数里有多处问题:
- 行检查循环:你当前的代码不管是否找到重复数字,直接
return 0,这会导致任何情况都返回不安全。正确的逻辑是找到重复才返回0,否则循环完继续:i = 0; while(i < SIZE) { if(matrix[r][i] == n) { return 0; // 找到重复,直接返回不安全 } i++; } - 列检查循环:同样先执行
i++导致漏掉索引0的元素,调整为先判断再递增:i = 0; while(i < SIZE) { if(matrix[i][c] == n) { return 0; } i++; } - 3x3区块检查:你把
row_start和col_start的赋值搞混了,而且计数器初始化顺序错误,还提前递增了i/j导致漏掉第一个元素:int row_start = (r/3)*3; int col_start = (c/3)*3; // 正确赋值列起始索引 i = row_start; while(i < row_start + 3) { j = col_start; while(j < col_start + 3) { if(matrix[i][j] == n) { return 0; } j++; } i++; }
3. solve_sudoku 函数的数字遍历遗漏
你初始化i=1后先执行i++,导致直接跳过了数字1的检查,应该先判断当前数字是否安全,再递增:
int solve_sudoku() { int row; int col; if(number_unassigned(&row, &col) == 0) return 1; int i = 1; while (i <= SIZE) { if (is_safe(i, row, col)) { matrix[row][col] = i; if(solve_sudoku()) return 1; matrix[row][col] = 0; } i++; // 先处理当前数字,再递增到下一个 } return 0; }
4. main 函数的输出笔误
你把错误提示写成了法语的le sudoku complet et juste,这和逻辑不符,应该改回原逻辑的错误提示(或者根据需求调整):
int main() { if (solve_sudoku()) { print_sudoku(); } else { printf("Error: No solution exists\n"); } return 0; }
完整修复后的代码
#include <stdio.h> #define SIZE 9 int matrix[9][9] = { {8,0,0,0,0,0,0,0,0}, {0,0,3,6,0,0,0,0,0}, {0,7,0,0,9,0,2,0,0}, {0,5,0,0,0,7,0,0,0}, {0,0,0,0,4,5,7,0,0}, {0,0,0,1,0,0,0,3,0}, {0,0,1,0,0,0,0,6,8}, {0,0,8,5,0,0,0,1,0}, {0,9,0,0,0,0,4,0,0} }; void print_sudoku() { int i = 0; int j; while(i < SIZE) { j = 0; while(j < SIZE) { printf("%d\t", matrix[i][j]); j++; } printf("\n\n"); i++; } } int number_unassigned(int *row, int *col) { int num_unassign = 0; int i,j; for(i=0;i<SIZE;i++) { for(j=0;j<SIZE;j++) { if(matrix[i][j] == 0) { *row = i; *col = j; num_unassign = 1; return num_unassign; } } } return num_unassign; } int is_safe(int n, int r, int c) { int i,j; // 检查行 i = 0; while(i < SIZE) { if(matrix[r][i] == n) { return 0; } i++; } // 检查列 i = 0; while(i < SIZE) { if(matrix[i][c] == n) { return 0; } i++; } // 检查3x3区块 int row_start = (r/3)*3; int col_start = (c/3)*3; i = row_start; while(i < row_start + 3) { j = col_start; while(j < col_start + 3) { if(matrix[i][j] == n) { return 0; } j++; } i++; } return 1; } int solve_sudoku() { int row; int col; if(number_unassigned(&row, &col) == 0) return 1; int i = 1; while (i <= SIZE) { if (is_safe(i, row, col)) { matrix[row][col] = i; if(solve_sudoku()) return 1; matrix[row][col] = 0; } i++; } return 0; } int main() { if (solve_sudoku()) { print_sudoku(); } else { printf("Error: No solution exists\n"); } return 0; }
这个修复后的代码可以正常运行并求解数独,核心问题都是while循环中计数器的递增顺序错误,以及变量赋值的逻辑错误,调整后就和原for循环的逻辑完全一致了。
内容的提问来源于stack exchange,提问作者zejuz
相关产品推荐
相关产品推荐

