数独棋盘生成器检查行列哈希表重复时程序无限运行
问题分析与修复方案
你的数独生成器陷入无限循环的核心问题出在checkMap方法的逻辑上——它在检查数字合法性的同时,直接修改了哈希表中的数据,导致后续位置无法找到合法数字,最终卡死在do-while循环里。
具体问题拆解
- 填充单元格时,先调用
checkValue检查行和列:先检查行,若数字合法,checkMap会直接把数字加到该行列表;接着检查列,若数字在列中已存在返回false,但此时行列表里已经错误加入了这个数字。 - 这种错误修改会导致该行后续单元格永远无法使用这个数字,当填充到后面的位置时,可能没有任何合法数字可选,程序就会无限循环生成随机数,永远找不到符合条件的值。
- 你添加
list.size() == 9的判断后,相当于强行跳过合法性检查,允许重复数字存在,所以程序能结束,但生成的棋盘自然不符合数独规则。
修复后的代码
import java.util.ArrayList; import java.util.HashMap; import java.util.Map; class Board { Map<String, ArrayList<Integer>> map = new HashMap<>(); int[][] board = new int[9][9]; public Board() { // 提前初始化所有行和列的空列表 for (int i = 0; i < 9; i++) { map.put("row" + i, new ArrayList<>()); map.put("col" + i, new ArrayList<>()); } for (int row = 0; row < board.length; row++) { for (int col = 0; col < board[row].length; col++) { int value; do { value = (int) (Math.random() * 9 + 1); } while (!isValid(row, col, value)); // 确认合法后再更新哈希表与棋盘 map.get("row" + row).add(value); map.get("col" + col).add(value); board[row][col] = value; } } } // 仅做合法性检查,不修改哈希表 boolean isValid(int row, int col, int value) { // 检查行重复 if (map.get("row" + row).contains(value)) { return false; } // 检查列重复 if (map.get("col" + col).contains(value)) { return false; } // 注:数独还需要检查3x3宫格重复,你原代码未实现这部分,若要生成合法数独需补充 return true; } }
关键修改点
- 分离检查与修改逻辑:把合法性判断和哈希表更新拆分开,只有确认数字合法后,才将其加入对应行和列的列表,避免错误修改数据。
- 提前初始化列表:构造函数中先创建所有行和列的空列表,避免后续操作出现空指针问题。
- 简化随机数生成:
Math.random() *9 +1本身就能生成1-9的整数,无需额外调用Math.floor。
内容的提问来源于stack exchange,提问作者Juan Manuel
相关产品推荐
相关产品推荐

