实现原理
见下面代码中的注释
代码及其测试输出
#include<iostream>
#include<vector>
#include<sstream>
using namespace std;
/*
- I used DFS to solve this problem, which is can thought as one kind of backtracking algorithm.
- To implement DFS, I used recursive call.
- In order to implement recursive calls, it is always a good idea to determine
the input of the recursive function and what the recursive function does.
- The input of DFS() is a integer n, which represents the position puzzle[n/9][n%9] in the 9*9 grid.
- For example, n = 41 represents the position (41/9 = 4, 41%9 = 5), i.e., puzzle[4][5].
- So the range of invalid n is 0 ~ 80.
- What does DFS(int n) do: DFS(int n) assumes that the numbers in positions 0~n-1 have been correctly placed,
and DFS(int n) tries to place numbers in positions n~80 correctly.
If DFS(int n) successfully places numbers at position n~80 correctly, then DFS returns true,
otherwise DFS returns false.
- How to implement DFS(int n): For more details, see the comments in DFS(int n);
- How to implement Solve(): Just call DFS(0);
*/
class SudokuSolver {
private:
int puzzle[9][9]{};
// An auxiliary function
// This function assumes that the number at position 0~n-1 has been placed correctly,
// and returns whether it is valid to place key at position n
bool check(int n, int key){
if(n > 80) return false;
int row = n / 9, col = n % 9;
int i, j;
// Check the row
for(i = 0; i < 9; ++i){
if(puzzle[row][i] == key)
return false;
}
// Check the column
for(i = 0; i < 9; ++i){
if(puzzle[i][col] == key)
return false;
}
// Check the Subgrid
int x = row/3 * 3, y = col/3 * 3;
for(i = 0; i < 3; ++i){
for(j = 0; j < 3; ++j){
if(puzzle[x+i][y+j] == key)
return false;
}
}
return true;
}
// DFS
bool DFS(int n){
if(n > 80) return true;
int row = n / 9, col = n % 9;
if(puzzle[row][col]){
// If the number in position n is given, just call DFS(n + 1);
return DFS(n + 1);
}else{
// If the number in position n is not determined
int i;
// Try to place number from 1 to 9 in position n
for(i = 1; i <= 9; ++i){
if(check(n, i)){
// If placing i in position n is valid, then place i in position n.
puzzle[row][col] = i;
if (DFS(n+1))
// If placing i in position and we can place numbers in position n+1~80 correctly, then return true.
return true;
else{
// If placing i in position and we cannot place numbers in position n+1~80 correctly
puzzle[row][col] = 0;
}
}
}
return false;
}
}
public:
explicit SudokuSolver(int (&p)[9][9]) {
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
puzzle[i][j] = p[i][j];
}
bool Solve() {
return DFS(0);
}
string Print() {
std::ostringstream os;
for(auto & i : puzzle) {
for (int j : i)
os << j << " ";
os << endl;
}
return os.str();
}
};
int main(){
int sudoku[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}};
SudokuSolver solver(sudoku);
if (solver.Solve()) {
cout<<"-------------------------"<<endl;
cout<<" SOLVED! "<<endl;
cout<<"-------------------------"<<endl;
cout << solver.Print();
}
else
cout << "Solution Does Not Exist!" << endl;
return 0;
}
代码输出如下所示:
-------------------------
SOLVED!
-------------------------
8 1 2 7 5 3 6 4 9
9 4 3 6 8 2 1 7 5
6 7 5 4 9 1 2 8 3
1 5 4 2 3 7 8 9 6
3 6 9 8 4 5 7 2 1
2 8 7 1 6 9 5 3 4
5 2 1 9 7 4 3 6 8
4 3 8 5 2 6 9 1 7
7 9 6 3 1 8 4 5 2