我是Java的新手。这是我试图制作数独求解器的尝试。截至目前,这还没有GUI,输入您必须修改代码本身的问题。通常程序在大约30毫秒内完成数独(从一些填充值开始),如果必须从头开始(从空白数据开始),则大约100毫秒。我遇到的问题是,有时程序在没有提供解决方案的情况下继续运行,我必须手动停止它。是因为数独只有一个或几个解决方案?还是因为它被卡住了某种循环。我还注意到,如果程序中填写了最远的最右边(8,8),甚至不会尝试解决数独。也许是因为我编写代码的方式,它认为数独已经解决了。我可以让它检查最后一个未填充点而不是固定位置吗?
package sudoku;
public class Sudoku {
static int userGrid[][]=new int[][]
{{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0,0}};//[Horizontal][Vertical]
static int grid[][]=new int[9][9];//Program experiments
public static void main(String[] args) {
for(int i=0;i<9;i+=1) {
for (int j=0;j<9;j+=1) {
grid[i][j]=userGrid[i][j];
}
}
print(grid);
double timeStart=System.currentTimeMillis();
print(loop(0, 0, grid));
double timeEnd=System.currentTimeMillis();
System.out.println("That took "+(timeEnd - timeStart)+" milliseconds to complete");
}
public static int[][] loop(int y, int x, int[][] grid) {
while(!validity(8, 8, grid) || grid[8][8]==0)//while it's not solved
{
if(userGrid[y][x]!=0){
int yy,xx;
if (x==8) {yy=y+1;xx=0;} else {yy=y; xx=x+1;}
loop(yy, xx, grid);
} else {
if(grid[y][x]<9) {//going forward
grid[y][x]+=1;
if(validity(y, x, grid)) {
int yy,xx;
if (x==8) {yy=y+1;xx=0;} else {yy=y; xx=x+1;}
loop(yy, xx, grid);
}
} else {
grid[y][x]=0;
break;}
}
}
return grid;
}
public static boolean validity(int x, int y, int[][] grid) {
String temp="";
for(int i=0;i<9;i+=1) {
temp+=Integer.toString (grid[i][y]);//horizontal
temp+=Integer.toString (grid[x][i]);//vertical
temp+=Integer.toString (grid[(x/3)*3+i/3][(y/3)*3+i%3]);//square
}
int count=0, idx=0;
while((idx=temp.indexOf(Integer.toString (grid[x][y]),idx))!=-1)
{idx+=1;count+=1;}
return count==3;
}
public static void print(int[][] grid) {
System.out.println();
for(int i=0;i<9;i+=1) {
for (int j=0;j<9;j+=1) {
System.out.print(grid[i][j]);
}
System.out.println();
}
}
}
编辑:我调试了代码并发现了问题
通过查找最后一个未填充的数字而不是最右下方的数字(8,8)来解决故障
我遇到的另一个问题是,它不会在预先存在的数字后面回溯并且会陷入无限循环。这就是它无休止地运行的原因。
固定代码:
package sudoku;
public class Sudoku {
static int userGrid[][]=new int[][]
{{2,0,0,4,0,0,0,0,0},
{0,0,4,0,9,0,0,0,0},
{0,0,0,0,6,0,8,7,0},
{7,0,2,0,0,0,0,8,0},
{0,0,0,7,0,0,0,0,9},
{0,4,9,0,0,2,0,0,5},
{0,8,0,0,0,7,1,9,3},
{0,5,0,0,0,4,0,0,0},
{0,0,0,8,0,0,0,0,0}};//[Horizontal][Vertical]
static int grid[][]=new int[9][9];//Program experiments
//static String pGrid[][]=new String[9][9];//Possibilities
public static void main(String[] args) {
for(int i=0;i<9;i+=1) {
for (int j=0;j<9;j+=1) {
grid[i][j]=userGrid[i][j];
}
}
print(grid);
double timeStart=System.currentTimeMillis();
int lastPos = findLastCell();
if (lastPos == 0){
return;
}
int lastY = lastPos % 16;
int lastX = lastPos / 16;
print(loop(0, 0, lastY, lastX, grid));
double timeEnd=System.currentTimeMillis();
System.out.println("That took "+(timeEnd - timeStart)+" milliseconds to complete");
}
public static int findLastCell(){
for (int i=8; i>=0; i--){
for (int j=8; j>=0; j--){
if (userGrid[i][j]==0){
return ((j * 16) + i);
}
}
}
return 0;
}
public static int[][] loop(int y, int x, int lastY, int lastX, int[][] grid) {
while(!validity(lastY, lastX, grid) || grid[lastY][lastX]==0)//while it's not solved
{
while (userGrid[y][x]!=0){
if (x==8)
{
// System.out.println("Here 2");
y=y+1;
x=0;
}
else
{
x=x+1;
}
}
if(grid[y][x]<9) {//going forward
grid[y][x]+=1;
if(validity(y, x, grid)) {
int yy,xx;
if (x==8)
{
//System.out.println("Here");
yy=y+1;
xx=0;
}
else
{
yy=y;
xx=x+1;
}
loop(yy, xx, lastY, lastX, grid);
}
} else {
grid[y][x]=0;
break;}
}
return grid;
}
public static boolean validity(int x, int y, int[][] grid) {
String temp="";
for(int i=0;i<9;i+=1) {
temp+=Integer.toString (grid[i][y]);//horizontal
temp+=Integer.toString (grid[x][i]);//vertical
}
for (int i=0; i<3; i++){
for (int j=0; j<3; j++){
temp+=Integer.toString (grid[(x/3)*3+i][(y/3)*3+j]);
//square (Java doesn't round the divided no.s if they
//are fractions. It jjust outputs them as 0
}
}
int count=0, idx=0;
while((idx=temp.indexOf(Integer.toString (grid[x][y]),idx))!=-1)
{idx+=1;count+=1;}
return count==3;
}
public static void print(int[][] grid) {
System.out.println();
for(int i=0;i<9;i+=1) {
for (int j=0;j<9;j+=1) {
System.out.print(grid[i][j]);
}
System.out.println();
}
}
}
然而,我会补充说,我收到的答案不太有帮助。