【发布时间】:2016-10-01 16:54:18
【问题描述】:
我正在制作一个数独求解器,它会尝试一个正方形中的所有可能值,如果没有找到解决方案,则回溯。我相信我有一个几乎可以工作的算法,但到目前为止它只在一个 16 单元拼图的第 0、2 和 3 行上工作。
public boolean fillBoard(int[][] board, int row, int col){
int index = 1; //Next value to try when an empty is found
boolean solved = false;
for(int i = row; i < width; i++){ //For each row
for(int j = col; j < height; j++){ //For each column
if(board[i][j]==0){ //0 represents empty
while(!solved){
board[i][j] = index;
if(checker.checkRow(board[i])
&& checker.checkColumn(columnToArray(board, j))
//&& checker.checkBox(<input>)
){
solved = fillBoard(board, i, 0);
}else{
if(index < width){
index++;
}else{
return false;
}
}
}
}
}
}
puzzle = copyPuzzle(board);
return true;
}
现在它不检查第三条数独规则,它只检查列和行。但是,它仍然应该返回一个遵循行和列规则的谜题,对吧?而checkBox方法一旦写好,应该就可以解谜了。我在哪里搞砸了?
编辑几个例子:
对于
的输入 {1, 2, 0, 0},
{0, 4, 0, 0},
{0, 0, 1, 0},
{0, 0, 3, 2}
程序返回
1 2 4 3
4 4 4 4
2 3 1 4
4 1 3 2
对于一个输入
{1, 0},
{2, 0}
它正确地解决了它。
对于
的输入 { 1, 0, 3, 4, 0, 0 },
{ 4, 0, 6, 0, 0, 3 },
{ 2, 0, 1, 0, 6, 0 },
{ 5, 0, 4, 2, 0, 0 },
{ 3, 0, 2, 0, 4, 0 },
{ 6, 0, 5, 0, 0, 2 }
它返回未解决的难题
编辑:checkRow 询问的人
public boolean checkRow(int[]row){
HashSet<Integer> set = new HashSet<Integer>();
for(int i = 0; i < row.length;i++){
if(!set.add(row[i]) && row[i]>0){//Duplicate?
return false;
}
}
return true;
}
【问题讨论】:
-
请提供它不起作用的具体示例。
-
@ScottHunter 我加了几个例子
-
checkRow和checkColumn是否只是验证当前行/列不包含0?递归的退化情况似乎定义不明确,这可以解释算法在最后一个实例中返回一个未解决的难题。我认为您的return true需要为return solved,并且solved的值需要针对您的基本情况进行更新。 -
@nbrooks
checkRow和checkColumn将行或列的值添加到集合中,除非值为 0,如果添加失败,则返回 false。他们正在检查以确保到目前为止,添加到行或列的所有值都在那里有效 -
@realmature 你可能想发布
checkRow和checkColumn的实现。另外,一个不相关的提示:尽量保持你的方法干净,没有太多的嵌套语句。有时整洁会导致问题突然出现。
标签: java