[英]Sudoku puzzle solver Java Implementation check
我正在嘗試使用 Java 實現數獨解謎器,但下面的代碼在第二種情況下失敗(它應該返回 false)。 從正在打印的輸出來看,看起來代碼甚至在解決整個網格之前就退出了。 我錯過了什么?
有人可以幫助快速檢查並提示您是否發現問題。
問題:編寫函數 sudokuSolve 來檢查給定的數獨板(即 9x9 數獨謎題)是否可解。 如果是這樣,該函數將返回 true。 否則(即給定的數獨板沒有有效的解決方案),返回 false。
代碼:
public class Sudoku {
static boolean sudokuSolve(char[][] board) {
int row = -1, col = -1;
List<Integer> candidates = null; // store smallest possible candidates
for (int r = 0; r < 9; r++) {
for (int c = 0; c < 9; c++) {
if (board[r][c] == '.') {
List<Integer> newCandidates = getCandidates(board, r, c);
if (candidates == null || newCandidates.size() < candidates.size()) {
candidates = newCandidates;
row = r;
col = c;
}
}
}
}
if (candidates == null || candidates.isEmpty())
return true;
for (Integer val : candidates) {
board[row][col] = (char) (val.intValue() + '0');
if (sudokuSolve(board))
return true;
else
board[row][col] = '.';
}
printGrid(board);
return false;
}
/**
* For each empty cell, consider 'newCandidates', the set of possible candidate
* values that can be placed into that cell.
*
*/
public static List<Integer> getCandidates(char[][] board, int x, int y) {
// filled row numbers
boolean[] mask = new boolean[10];
for (int row = 0; row < 9; row++) {
char ch = board[row][y];
if (ch != '.')
mask[ch - '0'] = true;
}
// filled col numbers
for (int col = 0; col < 9; col++) {
char ch = board[x][col];
if (ch != '.')
mask[ch - '0'] = true;
}
// filled subgrid numbers
// starts at row - row%3, col - col%3
int subBoardRow = x - (x % 3);
int subBoardCol = y - (y % 3);
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
char ch = board[subBoardRow + row][subBoardCol + col];
if (ch != '.')
mask[ch - '0'] = true;
}
}
List<Integer> candidates = new ArrayList<Integer>();
for (int i = 1; i <= 9; i++) {
if (!mask[i])
candidates.add(i);
}
return candidates;
}
public static void main(String[] args) {
char[][] board = new char[][] {
{'.','.','.','7','.','.','3','.','1'},
{'3','.','.','9','.','.','.','.','.'},
{'.','4','.','3','1','.','2','.','.'},
{'.','6','.','4','.','.','5','.','.'},
{'.','.','.','.','.','.','.','.','.'},
{'.','.','1','.','.','8','.','4','.'},
{'.','.','6','.','2','1','.','5','.'},
{'.','.','.','.','.','9','.','.','8'},
{'8','.','5','.','.','4','.','.','.'}};
System.out.println(sudokuSolve(board));
printGrid(board);
System.out.println("***************************************");
char[][] board2 = new char[][] {
{'.','8','9','.','4','.','6','.','5'},
{'.','7','.','.','.','8','.','4','1'},
{'5','6','.','9','.','.','.','.','8'},
{'.','.','.','7','.','5','.','9','.'},
{'.','9','.','4','.','1','.','5','.'},
{'.','3','.','9','.','6','.','1','.'},
{'8','.','.','.','.','.','.','.','7'},
{'.','2','.','8','.','.','.','6','.'},
{'.','.','6','.','7','.','.','8','.'}};
System.out.println(sudokuSolve(board2));
printGrid(board2);
}
public static void printGrid(char[][] grid) {
for (int r = 0; r < grid.length; r++) {
for (int c = 0; c < grid[0].length; c++) {
System.out.print(grid[r][c] + " ");
}
System.out.print("\n");
}
}
}
輸出:
true
6 5 8 7 4 2 3 9 1
3 1 2 9 8 6 4 7 5
7 4 9 3 1 5 2 8 6
2 6 3 4 9 7 5 . .
. . . 1 . . . . .
. . 1 2 . 8 . 4 .
. . 6 8 2 1 . 5 .
. . . 5 . 9 . . 8
8 . 5 6 . 4 . . .
***************************************
真 1 8 9 2 4 3 6 7 5 2 7 3 5 6 8 9 4 1 5 6 4 9 1 7 2 3 8 4 1 2 7 3 5 8 9 6 6 9 8 4 2 1 7 5 3 7 3 5 8 6 4 1 2 8 4 1 . 5 9 . 2 7 . 2 7 8 。 . . 6 . . . 6 . 7 . . 8 .
你的算法有點奇怪。
你有遞歸,這似乎沒用。 對於板上的每個瓷磚,您計算候選人,但用另一個瓷磚的候選人覆蓋它。 也許我錯了,但結果有時是正確的,但不應該。
sudokuSolve
無法以這種方式正常工作。
更新
第二個初始板是錯誤的。 4. 列中有兩個9 (從頭開始)。 您的算法無法處理這種情況。
要么問題是錯誤的,要么問題是(也)為初始板實施檢查器,或者您打錯了 ;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.