我正在尝试制作一个9 X 9 Sudoku随机生成的网格,但我遇到了问题。每次我运行程序时,它总是冻结,只显示或多或少5行随机生成的数字。我不会遇到4 X 4和6 X 6网格的问题,只有9 X 9.我不知道它为什么会一直冻结。我希望有一个人可以帮助我。这是我的代码。
public class Sudoku9x9
{
public static void main(String[] args)
{
Random rand = new Random();
int[][] sudoku = new int[9][9];
int rnum = 0;
for(int a = 0; a < 9; a++)
{
for(int b = 0; b < 9; b++)
{
boolean checkWhile = false;
while(checkWhile == false)
{
rnum = rand.nextInt(9) + 1;
if(CheckRow(a, b, sudoku, rnum) && CheckCol(a, b, sudoku, rnum)))
{
sudoku[a][b] = rnum;
checkWhile = true;
}
}
System.out.print(rnum + " ");
}
System.out.println("");
}
for(int a = 0; a < 9; a++)
{
for(int b = 0; b < 9; b++)
{
System.out.print(sudoku[a][b] + " ");
}
System.out.println("");
}
}
public static boolean CheckRow(int a, int b, int[][] sudoku, int rnum)
{
boolean check = true;
for(int c = b; c > 0; c--)
{
if(sudoku[a][c - 1] == rnum)
{
check = false;
}
}
return check;
}
public static boolean CheckCol(int a, int b, int[][] sudoku, int rnum)
{
boolean check1 = true;
for(int c = a; c > 0; c--)
{
if(sudoku[c - 1][b] == rnum)
{
check1 = false;
}
}
return check1;
}
}
答案 0 :(得分:1)
你的循环很慢,因为当你的程序填满大部分Sudoku时,很难生成一个适当的随机int来填充下一个槽,所以rnum
将被生成一次又一次并且许多重复的整数是产生。例如,如果只有一个数字可以使checkRow和checkCol为true,则生成它的概率为1/9!更糟糕的是,你的计划将陷入无法解决的境地!!!
所以你需要一个回溯计划,类似于八皇后问题。这是我的代码:
static int[][] sudoku = new int[9][9];
public static boolean CheckRow(int a, int b, int[][] sudoku, int rnum)
{
boolean check = true;
for(int c = b; c > 0; c--)
{
if(sudoku[a][c - 1] == rnum)
{
return false;
}
}
return check;
}
public static boolean CheckCol(int a, int b, int[][] sudoku, int rnum)
{
boolean check1 = true;
for(int c = a; c > 0; c--)
{
if(sudoku[c - 1][b] == rnum)
{
return false;
}
}
return check1;
}
public static boolean fill(int a, int b) {
Random rand = new Random();
int rnum = rand.nextInt(9) + 1;
boolean checkWhile = false;
for(int i = 0; i < 9 && !checkWhile; i++) {
if(CheckRow(a, b, sudoku, rnum) && CheckCol(a, b, sudoku, rnum))
{
sudoku[a][b] = rnum;
if(a == 8 && b == 8) return true;
if(b == 8) checkWhile = fill(a+1,0);
else checkWhile = fill(a,b+1);
}
if(rnum == 9) rnum = 1;
else rnum += 1;
}
return checkWhile;
}
public static void main(String[] args) {
fill(0,0);
for(int i = 0; i < 9; i++) {
for(int j = 0; j < 9; j++) {
System.out.print(sudoku[i][j]+" ");
}
System.out.println("");
}
}
答案 1 :(得分:0)
我可以发现一种避免不必要的检查的方法是更改你的检查方法,一旦发现错误就返回;
public static boolean CheckCol(int a, int b, int[][] sudoku, int rnum)
{
boolean check1 = true;
for(int c = a; c > 0; c--)
{
if(sudoku[c - 1][b] == rnum)
{
return false;
}
}
return check1;
}
也适用于行。
阅读locoyou的回答。此外,您的程序没有回溯功能,它可能会来到您的sodoku无法解决的地方,然后您需要回溯。您可能想要检查的数据的另一个重要元素是检查该号码所在的3x3框。