最近在本站看到某篇关于解数独的程序的博客,于是下载后尝试了下,发现有些数独是可以解的,但当我把下面这个数独放进去后,它不能够给我解出来:
{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0},
我并没有去看他的算法是什么样的,索性就直接自己重新写了个。在对fillNumber()方法的实现过程中对于嵌套调用让我收获颇多,深刻体会到了JAVA的传值问题。
现在把代码贴出与大家共享,请多多指正!
{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0},
我并没有去看他的算法是什么样的,索性就直接自己重新写了个。在对fillNumber()方法的实现过程中对于嵌套调用让我收获颇多,深刻体会到了JAVA的传值问题。
现在把代码贴出与大家共享,请多多指正!
import java.util.ArrayList;
import java.util.List;
public class Sudoku {
int[][] originalSudokuArray = null;
private static int[] oneToNine = {1,2,3,4,5,6,7,8,9};
private List<int[][]> collector = new ArrayList<int[][]>();
public Sudoku(int[][] sudokuArray){
this.originalSudokuArray = sudokuArray;
}
private void solveSudoku(){
fillNumber(originalSudokuArray,0,0);
printSudokuArray();
}
private void fillNumber(int[][] sudokuArray,int rowPosition,int colPosition){
for(int i=rowPosition;i<9;i++){
for(int j=0;j<9;j++){
if(sudokuArray[i][j]==0){
int[][] newSudokuArray = new int[9][9];
for(int number:oneToNine){//
if(numberIsLegal(sudokuArray,number,i,j)){
newSudokuArray = valueDeliver(sudokuArray);
newSudokuArray[i][j] = number;
if(hasNullBox(newSudokuArray)){
fillNumber(newSudokuArray,i,j);
}else{
collector.add(newSudokuArray);
return;
}
}
}
if(newSudokuArray[i][j]==0){
sudokuArray[rowPosition][colPosition] = 0;
}
return;
}
}
}
return;
}
private int[][] valueDeliver(int[][] sudokuArray){
int[][] newArray = new int[sudokuArray.length][sudokuArray[0].length];
for(int i=0,len=sudokuArray.length;i<len;i++){
for(int j=0,len1=sudokuArray[0].length;j<len1;j++){
newArray[i][j] = sudokuArray[i][j];
}
}
return newArray;
}
private boolean numberIsLegal(int[][] sudokuArray,int number,int rowPosition,int colPosition){
boolean legal = true;
//水平
for(int i=0;i<9;i++){
if(sudokuArray[rowPosition][i]==0) continue;
if(sudokuArray[rowPosition][i]==number){
legal = false;
}
}
//垂直
for(int i=0;i<9;i++){
if(sudokuArray[i][colPosition]==0) continue;
if(sudokuArray[i][colPosition]==number){
legal = false;
}
}
//九格
int boxRowStart = (rowPosition/3)*3;
int boxColStart = (colPosition/3)*3;
for(int i=boxRowStart;i<boxRowStart+3;i++){
for(int j=boxColStart;j<boxColStart+3;j++){
if(sudokuArray[i][j]==0) continue;
if(sudokuArray[i][j]==number){
legal = false;
}
}
}
return legal;
}
private boolean hasNullBox(int[][] sudokuArray){
boolean nullFlag = false;
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
if(sudokuArray[i][j]==0){
nullFlag = true;
}
}
}
return nullFlag;
}
private void printSudokuArray(){
for(int[][] intArray:collector){
for(int i=0;i<9;i++){
for(int j=0;j<9;j++){
System.out.print(intArray[i][j]+" ");
}
System.out.println();
}
System.out.println("---------------------------------");
}
System.out.println("总共"+collector.size()+"个解!");
}
public static void main(String[] args){
int[][] originalArray = {
{8,0,0,0,0,0,0,0,0},
{0,0,0,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0},
};
Sudoku sdk = new Sudoku(originalArray);
sdk.solveSudoku();
}
}
//测试数据:
//4个解
//{0,0,0,0,0,0,0,0,0},
//{0,0,0,0,0,1,0,0,3},
//{0,0,0,9,3,2,6,8,1},
//{6,5,0,2,9,0,7,3,8},
//{7,3,0,8,0,5,4,6,9},
//{9,0,0,0,7,3,5,1,2},
//{2,1,5,3,4,7,8,9,6},
//{4,6,8,1,2,0,0,0,7},
//{3,7,9,5,8,6,1,0,0},
//1个
//{1,0,0,0,6,0,0,0,7},
//{0,9,6,7,0,1,0,4,0},
//{0,4,7,0,3,0,6,8,0},
//{6,5,0,2,0,4,7,0,8},
//{0,0,2,0,0,5,4,6,0},
//{0,8,4,6,0,3,0,0,2},
//{0,1,5,0,4,0,8,9,0},
//{4,0,8,1,0,9,3,0,5},
//{3,7,0,5,0,6,0,2,4},
//1个
//{8,0,0,0,0,0,0,0,0},
//{0,0,3,6,0,0,0,0,0},
//{0,7,0,0,9,0,2,0,0},
//{0,5,0,0,0,7,0,0,0},
//{0,0,0,0,4,5,7,0,0},
//{0,0,0,1,0,0,0,3,0},
//{0,0,1,0,0,0,0,6,8},
//{0,0,8,5,0,0,0,1,0},
//{0,9,0,0,0,0,4,0,0},
//比上面只少了一个数字,1634个解
//{8,0,0,0,0,0,0,0,0},
//{0,0,0,6,0,0,0,0,0},
//{0,7,0,0,9,0,2,0,0},
//{0,5,0,0,0,7,0,0,0},
//{0,0,0,0,4,5,7,0,0},
//{0,0,0,1,0,0,0,3,0},
//{0,0,1,0,0,0,0,6,8},
//{0,0,8,5,0,0,0,1,0},
//{0,9,0,0,0,0,4,0,0},