【发布时间】:2020-08-07 19:28:05
【问题描述】:
solveSudoku 函数是从 main() 函数调用的。
我写了以下解决数独的函数:
bool isFull(vector<vector<char>>& board){
for(int i = 0 ; i < board.size(); i++){
for(int j = 0 ; j < board[0].size(); j++){
if(board[i][j] == '.') return false;
}
}
return true;
}
vector<int> poss(vector<vector<char>>& board, int x, int y){
vector<int> ans;
set<int> s;
//check across columns
for(int j = 0 ; j < board[0].size(); j++){
if(board[x][j]!='.') s.insert(board[x][j] -'0');
}
//check acroos rows
for(int i = 0 ; i < board.size(); i++){
if(board[i][y]!='.') s.insert(board[i][y] - '0');
}
//check in square
int r, c;
if(x>=0 && x<=2) r = 0;
if(x>=3 && x<=5) r = 3;
if(x>=6 && x<=8) r = 6;
if(y>=0 && y<=2) c = 0;
if(y>=3 && y<=5) c = 3;
if(y>=6 && y<=8) c = 6;
for(int i = r; i <= r + 2; i++){
for(int j = c; j <= c + 2; j++){
if(board[i][j]!='.') s.insert(board[i][j]-'0');
}
}
for(int n = 1; n <=9 ; n++){
if(s.find(n) == s.end()){
ans.push_back(n);
}
}
return ans;
}
vector<int> Fempty(vector<vector<char>>& board){
vector<int> ans;
for(int i = 0; i < board.size(); i++){
for(int j = 0; j < board[0].size(); j++){
if(board[i][j] == '.'){
ans.push_back(i);
ans.push_back(j);
return ans;
}
}
}
return ans;
}
void solveSudoku(vector<vector<char>>& board) {
if(isFull(board)) return;
//not full
//Fempty returns first empty cell coordinate
vector<int> empty = Fempty(board);
int xe = empty[0], ye = empty[1];
//poss returns the vector of possible values
vector<int> pos = poss(board, xe, ye);
if(!pos.empty()){
for(int i = 0; i < pos.size(); i++){
board[xe][ye] = pos[i] + '0';
solveSudoku(board);
}}
board[xe][ye] = '.';
return;
}
当在main() 函数中调用solveSudoku 时,输入数独作为参数给出。它由1 到9 和. 之间的字符组成,表示空字符。 solveSudoku 函数的工作是正确填充数独中的所有元素(更改 board 中的值)。
当我运行这个程序时,我的输出没有变化。
如果我注释掉 board[xe][ye] = '.',我的输出会显示一些变化,但在单元格用完可能的值后它保持不变。
编辑:已知board有解决方案。
我做错了什么?
【问题讨论】:
-
When I run this program my output shows no change.你在哪里输出?如果在 main 当然你看不到任何变化,因为根据定义,最后 solveSudoku 返回 board 不变。您必须在if(isFull(board))before 到return时输出板,而不是仅仅到return;。当然你需要board[xe][ye] = '.'; -
当
isFull返回true时打印板子。 -
推荐:加
main。奖励点会改变main,如果您输入一组公开的输入,这些输入会暴露您想要处理的行为。 -
但是我只看到
board[xe][ye] = '.';必须在if(!pos.empty()){之后移动到for之后,而不是在if之后 -
您的
solveSudoku函数需要在找到解决方案时停止。您的基本情况是董事会已经满员(已解决)。然后继续将第一个空单元格设置为不同的值并调用solveSudoku,直到它返回true(已解决)或者您的值不足(在当前配置中不可能)。
标签: c++ recursion backtracking recursive-backtracking