Java实现无宫数独时9x9数组无法完成填充问题咨询
代码逻辑问题说明
你的代码核心问题不是do-while语法错误,是填充策略存在必然触发死循环的缺陷:
- 你采用逐格顺序填充、重复就重roll 1-9随机数的无回溯贪心逻辑,填充过程中极容易走到死局:当填到某一个单元格时,1-9范围内的所有数字,要么已经在当前行被前面填过的单元格占用,要么已经在当前列被同列其他行的单元格占用,此时不管循环多少次生成1-9的随机数,都不可能通过
check校验,do-while会无限运行,表现为程序卡死。 - 你提到在do-while里给随机数加10就能正常填充,本质是钻了逻辑的空子:do-while块里生成的数值范围变成11-19,而之前填充的所有单元格数值都是1-9,新生成的数天然不会和已填充的行、列数值重复,第一次循环就能通过
check校验,当然不会卡死,但此时填充的数组根本不符合简化数独“使用1-9数字、行列无重复”的要求,只是规避了死循环而已。 - 代码里外层的
if (!(check(nines,i,j)))判断是冗余代码,不管第一次生成的随机数是否合法,都可以直接进入do-while逻辑校验,这部分不影响运行结果,只是不必要的代码。 - 额外排查点:如果你的
check方法实现有误,把当前单元格自身和自己做重复校验,也会导致永远返回false触发死循环,但结合你加10后程序可以正常运行的现象,这个问题可以排除,核心故障原因还是无回溯随机填充的死局问题。
修复方向
你可以二选一调整填充逻辑,从根源避免死局:
- 加入回溯机制:采用深度优先搜索的思路填充,填当前格时按顺序尝试1-9的合法值,如果所有值都无法满足校验规则,就回退到上一个单元格,更换上一个单元格的取值后再继续向后填充,这种方式可以100%生成符合要求的数组,不会出现死局。
- 按行填充优化:填每一行时,先生成1-9的随机打乱序列,再校验序列每个位置的数是否和同列已填充的数重复,如果存在重复就重新打乱当前行的序列,直到整行所有数都满足同列不重复要求,这种方式比逐格随机roll值的效率高很多,实现难度也比回溯低。
内容的提问来源于stack exchange,提问作者Kaura Sankaran
相关产品推荐
相关产品推荐

