java - 我的数独回溯算法仅在部分时间有效,有人可以帮我改进吗?
问题描述
我有一个递归算法,它应该采用部分或完全空的数独板(表示一个 int[][],其中 0 表示一个空格)并填充它。它适用于空板和我输入的大多数其他板,但有时我会收到指向第 54 行和第 40 行的堆栈溢出错误(在语句 grid = copyGrid(emptyFill(grid, current + 1, cant)); )有人能帮忙吗我改进它?
//Creating and filling a board Recursive Methods
//Current represents the index for every cell on the board from 0 to 80 inclusive
//cant holds an array of values that the function may not place for each index
public static int[][] emptyFill(int[][] grid, int current, int[][] cant){
if(isFull(grid)){
return grid;
}
else if(getCellAt(grid, current) == 0){
for(int i = 1; i <= 9; i ++){
if(works(i, current / 9, current % 9, grid) && notInCant(cant, current, i)){
grid[current / 9][current % 9] = i;
//Line 40 below this comment
grid = copyGrid(emptyFill(grid, current + 1, cant));
return grid;
}
}
/*Backtracks backwards if no number was found by keeping track of what numbers we have tried. Should clear
up the cant list if we backtrack further than it */
for(int i = current; i < cant.length; i ++){
clearRow(cant, i);
}
addToRow(cant, current - 1, getCellAt(grid, current - 1));
setCellTo(grid, current, 0);
setCellTo(grid, current - 1, 0);
//Line 54 below this comment
grid = copyGrid(emptyFill(grid, current -1, cant));
return grid;
}
else{
grid = copyGrid(emptyFill(grid, current + 1, cant));
return grid;
}
}
解决方案
设法修复它,问题是当程序无法填写单元格时,它会通过清除当前和上一个单元格来“回溯”,更新无法放置的数字列表,然后调用程序再次。这会导致函数被调用太多次。新函数只是简单地清除单元格并在找不到合适的数字时退出该函数。这允许函数在不再次调用自身的情况下回溯,并且实际上返回到上一个调用。这是更新的功能。
public boolean emptyFill(int[][] grid, int current){
if(isFull(grid)){
return true;
}
else if(getCellAt(grid, current) == 0){
for(int i = 1; i <= 9; i ++){
if(works(i, current / 9, current % 9, grid) && notInCant( current, i)){
grid[current / 9][current % 9] = i;
if( emptyFill(grid, current + 1)) return true;
grid[current / 9][current % 9] = 0;
}
}
return false;
}
else{
return emptyFill(grid, current + 1);
}
}
推荐阅读
- python - 改进此循环以使其更可python化的方法
- angular - *ngIf - 如何在模板中进行空检查
- javascript - 角度未将主体传递给 PUT 方法
- python - 无法使用 Selenium 输入文本
- python - 在 SonarQube 的库中 nextNot 函数究竟做了什么?
- java - 如何在 Spark 流中使用 Spark 内部的 Kafka 实现偏移管理?
- highcharts - 带有时间戳和非十进制 y 轴的 highstocks 日内图表
- ios - UIPickerView 有多个组件时如何只显示一个组件?
- java - Spring Boot 应用程序在 Vaadin 13 (Flow 1) 兼容模式下运行,而不是在 Vaadin 14 中运行
- java - 在我的 RecyclerView On Item Click Listener 中,Listener 为 null