我正在使用数独求解器,并且无法正确返回/结束求解器函数。 show()
函数中的moveOn()
被调用,它显示已完成的数独,但解决方法返回false。我试图在问题解决时解决返回true,当它不可解决但是不知道如何完成此操作时返回null。
L
是电路板的长度(9 x 9数独将有L = 9)
getSquare(r,c)
返回表示数独板的二维数组中的值
不同的检查功能检查一个值是否适合特定位置。他们不是问题。
show()
函数在控制台中打印出数组,因此它看起来像是一个合适的数独板。
我还有一个检查2D数组的isSolved()
函数,如果它是有效的解析数据,则返回true,otherweise返回false。我试图在solve()
方法中实现这一点,希望使用它来返回true,但是没有成功
//This method's only purpose it to call the findNum function on the next location in the sudoku
public void moveOn(int row, int column) {
//if the previous location was not the last in the row move to ne next cell in said row.
//if it was the last location in the row, move to the first column of the next row
if (column + 1 != L) {solve(row, column + 1);}
else if (row + 1 != L) {solve(row + 1, 0);}
else {show();}
}
//This method finds a valid number for a specific location on the sudoku grid\
public boolean solve(int row, int column) {
if (row >= L) {return true;}
//pass over any numbers that are not empty
if (getSquare(row, column) != 0) {moveOn(row, column);}
else {
//attempt to find a valid number for the location
for (int n = 1; n <= L; n++) {
if (checkRow(row, n) && checkCol(column, n) && checkSquare(row, column, n)) {
// If a number is allowed at a specific location set that location to the number
setSquare(row, column, n);
//Begin checking for a solution based on previous numbers changed
moveOn(row, column);
}
}
//If no number is allowed in this space backtrack to the last successful number
//changed and reset all locations that have been changed recursively
setSquare(row, column, 0);
}
//If the puzzle is unsolveable
return false;
}
非常感谢任何能够帮助阐明情况的人。 如果需要更多我的代码/信息,我很乐意提供
示例输入文件:http://pastebin.com/6mSKT3ES
编辑:删除完整代码
答案 0 :(得分:2)
return
函数中只有一个solve
语句,即
return false;
并且由于这是函数中的最后一个语句,并且无条件执行,solve
除非抛出异常,否则始终返回false
。
要获得实际告诉您是否找到解决方案的返回值,您需要使返回值取决于条件。此外,一旦你找到了解决方案,对于精心设计的谜题,继续搜索是没有意义的。
因此,您应该在搜索循环中添加条件return true;
。为此,您需要知道何时找到解决方案。您将递归包装在对moveOn
的中间调用中,因此最简单的更改是将返回值添加到moveOn
:
public boolean moveOn(int row, int column) {
//if the previous location was not the last in the row move to ne next cell in said row.
//if it was the last location in the row, move to the first column of the next row
if (column + 1 != L) {return solve(row, column + 1);}
else if (row + 1 != L) {return solve(row + 1, 0);}
else {show(); return true;} // reached end of grid, solved
}
并在`solve'中使用它:
public boolean solve(int row, int column) {
//pass over any numbers that are not empty
if (getSquare(row, column) != 0) {return moveOn(row, column);}
else {
//attempt to find a valid number for the location
for (int n = 1; n <= L; n++) {
if (checkRow(row, n) && checkCol(column, n) && checkSquare(row, column, n)) {
// If a number is allowed at a specific location set that location to the number
setSquare(row, column, n);
//Begin checking for a solution based on previous numbers changed
if (moveOn(row, column)) {
return true; // solved, yay!
}
}
}
//If no number is allowed in this space backtrack to the last successful number
//changed and reset all locations that have been changed recursively
setSquare(row, column, 0);
}
//If the puzzle is unsolveable
return false;
}
答案 1 :(得分:-1)
This code works...
import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
public class Sudoku {
public static int suRows=9;
public static int suColumns=9;
public static int [][] suArray = new int[suRows][suColumns];
public static int [] dummyRowArray = new int[suRows];
public static int [] dummyColArray = new int[suColumns];
public static int [][] dummy3x3Array = new int[3][3];
public static int [] dummyArray = new int[9];
//read the contents of the file into a 2 dimensional array
public static void readSudoku() throws FileNotFoundException, IOException
{
System.out.print("Please enter the full file name containing the Sudoku Puzzle (e.g:X:/sudoku_case1.txt):");
Scanner scan = new Scanner (System.in);
String filename = scan.nextLine();
File file = new File( filename );
if ( file.exists() )
{
Scanner inFile = new Scanner( file );
for(int i=0; i<suRows; i++)
{
for(int j=0; j<suColumns; j++)
{
if(inFile.hasNextInt()) suArray[i][j] = inFile.nextInt();
}
}
inFile.close();
}
}
public static boolean inOrder(int [] a, int i, int j)
{
return a[i]<=a[j];
}
public static void swap(int [] a, int i, int j)
{
int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
public static void exchangeSort(int [] a)
{
for(int i=0;i<a.length;i++)
{
for(int j=1;j<a.length-i;j++)
{
if(!inOrder(a,j-1,j)) swap(a,j-1,j);
}
}
}
public static void displaySudoku(int [][] suArray)
{
for(int i=0; i<suArray.length;i++)
{
for(int j=0; j<suArray[i].length;j++)
{
System.out.print(suArray[i][j]);
System.out.print(" ");
}
System.out.println();
}
}
//Check if there are any more zeros
public static boolean isComplete(int [][]suArray)
{
boolean result=true;
//Check every element for 0
for(int i=0; i<suArray[0].length; i++)
{
for(int j=0 ; j<suRows ; j++)
{
if(suArray[i][j]==0) return false;
}
}
System.out.println("There are no zeros in this Sudoku");
return result;
}
//Check for adjacent duplicates
public static boolean isAdjacentDup(int [] a)
{
for(int i=1; i<a.length; i++)
{
if((a[i-1]!=0 || a[i]!=0))
{
if(a[i-1]==a[i]) return true;
}
}
return false;
}
//Check for 1 through 9
public static boolean is1to9(int [] a)
{
int j=1;
for(int i=0; i<a.length; i++)
{
if(a[i]==j) j++;
else return false;
}
return true;
}
public static boolean isDuplicate(int [][]suArray)
{
boolean result=false;
//Check every row for duplicates
for(int i=0; i<suArray[0].length; i++)
{
for(int j=0 ; j<suRows ; j++)
{
dummyRowArray[j]=suArray[i][j];
}
//Sort dummyArray so that duplicates can be checked
exchangeSort(dummyRowArray);
//Now check Adjacent elements for duplicates
if(isAdjacentDup(dummyRowArray)==true)
{
System.out.println("Duplicates are found in row");
return true;
}
}
displaySudoku(suArray);
//Check every column for duplicates
for(int j=0; j<suArray[0].length; j++)
{
for(int i=0 ; i<suColumns ; i++)
{
dummyColArray[i]=suArray[i][j];
}
//Sort dummyArray so that duplicates can be checked
exchangeSort(dummyColArray);
//Now check Adjacent elements for duplicates
if(isAdjacentDup(dummyColArray)==true)
{
System.out.println("Duplicates are found in columns");
return true;
}
}
displaySudoku(suArray);
System.out.println("3X3:");
//Check every 3X3 matrix for duplicates
// 1st block
if(is3x3Duplicate(suArray,0,3,0,3)==true)
{
System.out.println("1st Block has a duplicate");
return true;
}
else System.out.println("1st Block has no duplicate");
// 2nd block
if(is3x3Duplicate(suArray,0,3,3,6)==true)
{
System.out.println("2nd Block has a duplicate");
return true;
}
// 3rd block
if(is3x3Duplicate(suArray,0,3,6,9)==true)
{
System.out.println("3rd Block has a duplicate");
return true;
}
// 4th block
if(is3x3Duplicate(suArray,3,6,0,3)==true)
{
System.out.println("4th Block has a duplicate");
return true;
}
// 5th block
if(is3x3Duplicate(suArray,3,6,3,6)==true)
{
System.out.println("5th Block has a duplicate");
return true;
}
// 6th block
if(is3x3Duplicate(suArray,3,6,6,9)==true)
{
System.out.println("6th Block has a duplicate");
return true;
}
// 7th block
if(is3x3Duplicate(suArray,6,9,0,3)==true)
{
System.out.println("7th Block has a duplicate");
return true;
}
// 8th block
if(is3x3Duplicate(suArray,6,9,3,6)==true)
{
System.out.println("8th Block has a duplicate");
return true;
}
// 9th block
if(is3x3Duplicate(suArray,6,9,6,9)==true)
{
System.out.println("9th Block has a duplicate");
return true;
}
return result;
}
//Check every3X3 grid for duplicates
public static boolean is3x3Duplicate(int [][]suArray, int x1, int x2, int y1, int y2)
{
boolean result=false;
int k=0, l=0;
for(int i=x1; i<x2;i++)
{
for(int j=y1;j<y2;j++)
{
dummy3x3Array[k][l]=suArray[i][j];
l++;
}
l=0;
k++;
}
displaySudoku(dummy3x3Array);
for(int i=0; i<dummy3x3Array.length; i++)
{
for(int j=0; j<dummy3x3Array.length; j++)
{
dummyArray[(i*dummy3x3Array.length) + j] = dummy3x3Array[i][j];
}
}
System.out.println(Arrays.toString(dummyArray));
//Sort dummyArray so that duplicates can be checked
exchangeSort(dummyArray);
//Now check Adjacent elements for duplicates
if(isAdjacentDup(dummyArray)==true)
{
System.out.println("Duplicates are found in blocks");
return true;
}
return result;
}
//Check every3X3 grid for 1 trough 9
public static boolean is3x3have1to9(int [][]suArray, int x1, int x2, int y1, int y2)
{
boolean result=false;
int k=0, l=0;
for(int i=x1; i<x2;i++)
{
for(int j=y1;j<y2;j++)
{
dummy3x3Array[k][l]=suArray[i][j];
l++;
}
l=0;
k++;
}
for(int i=0; i<dummy3x3Array.length; i++)
{
for(int j=0; j<dummy3x3Array.length; j++)
{
dummyArray[(i*dummy3x3Array.length) + j] = dummy3x3Array[i][j];
}
}
//Sort dummyArray so that duplicates can be checked
exchangeSort(dummyArray);
//Now check Adjacent elements for duplicates
if(is1to9(dummyArray)==false)
{
System.out.println("Block doe snot have 1 through 9");
return false;
}
return result;
}
public static boolean isValidSudoku(int [][] suArray)
{
// boolean result=true;
//All nos should be between 0 and 9
for(int i=0; i<suArray.length; i++)
{
for(int j=0; j<suArray[i].length; j++)
{
if(suArray[i][j]<0 || suArray[i][j]>9){
System.out.println("Nos in the puzzle are out of range");
return false;
}
}
}
//Call teh isDuplicate function to check for duplicates in the rows
if( isDuplicate(suArray)==true) return false;
return true;
}
public static boolean isSolvedSudoku(int [][] suArray)
{
//Check every row for 1 to 9
for(int i=0; i<suArray[0].length; i++)
{
for(int j=0 ; j<suRows ; j++)
{
dummyRowArray[j]=suArray[i][j];
}
//Sort dummyArray so that duplicates can be checked
exchangeSort(dummyRowArray);
if(is1to9(dummyRowArray)==false)
{
System.out.println("1 through 9 not present in rows");
return false;
}
}
//Check every column for 1 to 9
for(int j=0; j<suArray[0].length; j++)
{
for(int i=0 ; i<suColumns ; i++)
{
dummyColArray[i]=suArray[i][j];
}
//Sort dummyArray so that duplicates can be checked
exchangeSort(dummyColArray);
//Now check Adjacent elements for duplicates
if(is1to9(dummyColArray)==false)
{
System.out.println("1 through 9 not present in columns");
return false;
}
}
//Check every 3X3 matrix for 1 through 9
// 1st block
if(is3x3have1to9(suArray,0,3,0,3)==true)
{
System.out.println("1st Block does not contain 1 through 9");
return false;
}
// 2nd block
if(is3x3have1to9(suArray,0,3,3,6)==true)
{
System.out.println("2nd Block does not contain 1 through 9");
return false;
}
// 3rd block
if(is3x3have1to9(suArray,0,3,6,9)==true)
{
System.out.println("3rd Block does not contain 1 through 9");
return false;
}
// 4th block
if(is3x3have1to9(suArray,3,6,0,3)==true)
{
System.out.println("4th Block does not contain 1 through 9");
return false;
}
// 5th block
if(is3x3have1to9(suArray,3,6,3,6)==true)
{
System.out.println("5th Block does not contain 1 through 9");
return false;
}
// 6th block
if(is3x3have1to9(suArray,3,6,6,9)==true)
{
System.out.println("6th Block does not contain 1 through 9");
return false;
}
// 7th block
if(is3x3have1to9(suArray,6,9,0,3)==true)
{
System.out.println("7th Block does not contain 1 through 9");
return false;
}
// 8th block
if(is3x3have1to9(suArray,6,9,3,6)==true)
{
System.out.println("8th Block does not contain 1 through 9");
return false;
}
// 9th block
if(is3x3have1to9(suArray,6,9,6,9)==true)
{
System.out.println("9th Block does not contain 1 through 9");
return false;
}
return true;
}
public static boolean solveSudoku(int [][] s)
{
//Check if Valid
if(isValidSudoku(suArray)==true) System.out.println("Sudoku is valid");
else
{
System.out.println("Not valid!");
return false;
}
//Check if Complete - No 0's in any place
if(isComplete(suArray)==true)
{
System.out.println("Sudoku is Complete");
return true;
}
else System.out.println("Sudoku is not Complete");
//Check if solved - 1-9 present in every row, column and 3x3
if(isSolvedSudoku(suArray)==true) System.out.println("Sudoku is Solved!");
else System.out.println("Not Solved");
//Locate the first 0 in the Sudoko puzzle
for(int i=0; i<suArray.length; i++)
{
for(int j=0 ; j<suArray[i].length ; j++)
{
if(suArray[i][j]==0)
{
System.out.println("0 found in location: " + i +" " + j );
for(int k=1;k<10;k++)
{
suArray[i][j]=k;
System.out.println("New value assigned to Sudoku: " + k);
displaySudoku(suArray);
if(solveSudoku(suArray))// isValidSudoku(suArray))
{
displaySudoku(suArray);
System.out.println("New value assigned to Sudoku");
return true;
}
}
suArray[i][j]=0;
return false; // remove this
}
}
}
return true;
}
public static void main(String[] args) throws FileNotFoundException, IOException {
readSudoku();
displaySudoku(suArray);
if( (isValidSudoku(suArray)!=true))
{
System.out.println("The given Sudoku Puzzle is not Valid!. Exiting....");
System.exit(0);
}
do
{
if(isSolvedSudoku(suArray)==true)
{
System.out.println("Sudoku is Completely Solved!");
}
if(solveSudoku(suArray)==true)
{
System.out.println("Sudoku is now solved");
}
else System.out.println("Not Complete");
}while(isSolvedSudoku(suArray)!=true);
System.out.println("Sudoku is now completely solved:");
displaySudoku(suArray);
}
}