我在c中做了一个数独求解器,我的递归函数只适用于第一行而不是停止。它查找值为零的第一个元素并填充它然后查找下一个值,并用另一个解决方案填充它。解决了它停止的第一行后,如何启用canSolve
,递归函数遍历整个板... sudokuGrid
也是全局的。
//this function makes a list of possible values for an empty cell, candidateList.
//candidateList is global so it the list can be accesed by the recursive solver function:
//canSolve();
void verifyCell(int x, int y){
int i;
int j;
for (i=0; i<9; i++){
candidateList[i] = 0;
}
//Rows
for (j=0; j<cols; j++){
if(sudokuGrid[x][j] != 0){
candidateList[sudokuGrid[x][j] - 1] = 1;
}
}
//Columns
for (i=0; i<rows; i++){
if(sudokuGrid[i][y] != 0){
candidateList[sudokuGrid[i][y] - 1] = 1;
}
}
//blocks
int startRow = ((x/3)*3);
int startCol = ((x/3)*3);
for (i = startRow; i<startRow+3; i++){
for(j=startCol;j<startCol+3;j++){
if(sudokuGrid[i][j] != 0){
candidateList[sudokuGrid[i][j] - 1] = 1;
}
}
}
for(i = 0; i<9;i++){
if (candidateList[i]==0){
candidateList[i] = i+1;
}else{
candidateList[i] = 0;
}
}
return;
}
canSolve(){
int i;
int j;
int x;
int y;
x= 0;
y = 0;
//gridToString();
if (isSolved()==1){
printf("Great this grid is Solved!\n");
gridToString();
return;
}
for(i=0;i<rows;i++){
for(j=0;j<cols;j++){
if(sudokuGrid[i][j]==0){
x=i;
y=j;
}
}
goto rest;
}
printf("(%d, %d)", x, y);
rest:;
verifyCell(x,y);
for(i = 0; i<rows; i++){
printf("%d", candidateList[i]);
if (candidateList[i] != 0){
sudokuGrid[x][y]=candidateList[i];
gridToString();
canSolve();//By the end of solving the first row it stops
}else{
sudokuGrid[x][y]=sudokuGrid[x][y];
}
}
}
答案 0 :(得分:0)
将递归与全局变量结合使用通常不是一个好主意。如果你的求解器做出了错误的选择并且需要回溯它,那么还需要将板恢复到它做出选择时的状态。
那你需要做什么?
我想你需要在尝试下一个候选人之前擦掉剩余的棋盘:
canSolve();//By the end of solving the first row it stops
wipeRestOfBoard(x,y); // Put 0 in sudokuGrid[x,y] and subsequent positions
}else{