package info.frady; public class SudokuSolver { public void solveSudoku(char[][] board) { solve(board); } public boolean solve(char[][] board){ for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ if(board[i][j]=='.'){ for(int k=0;k<9;k++){ board[i][j]=(char) ('1'+k); if(isValid(board, i, j)&&solve(board)) return true; board[i][j]='.'; } return false; } } } return true; } private boolean isValid(char[][] board,int x,int y){ for(int i=0;i<9;i++) if(i!=x&&board[i][y]==board[x][y]) return false; for(int j=0;j<9;j++) if(j!=y&&board[x][j]==board[x][y]) return false; for(int i=3*(x/3);i<3*(x/3+1);i++){ for(int j=3*(y/3);j<3*(y/3+1);j++){ if((i!=x||j!=y)&&board[i][j]==board[x][y]) return false; } } return true; } public static void main(String[] args) { char[][] board={ {'5','3','.','.','7','.','.','.','.'}, {'6','.','.','1','9','5','.','.','.'}, {'.','9','8','.','.','.','.','6','.'}, {'8','.','.','.','6','.','.','.','3'}, {'4','.','.','8','.','3','.','.','1'}, {'7','.','.','.','2','.','.','.','6'}, {'.','6','.','.','.','.','2','8','.'}, {'.','.','.','4','1','9','.','.','5'}, {'.','.','.','.','8','.','.','7','9'}, }; new SudokuSolver().solveSudoku(board); for(int i=0;i<9;i++){ for(int j=0;j<9;j++) System.out.print(board[i][j]+" "); System.out.println(); } } }
这个是我写的,复杂的应该解不出来,因为算法中未包含某些特殊情况。
package info.frady; import java.util.ArrayList; import java.util.List; import java.util.Scanner; /** * * 2016.7.4 3 2 4 8 9 1 5 6 7 8 1 9 7 6 5 2 4 3 7 5 6 3 4 2 1 9 8 6 7 1 4 5 3 8 2 9 4 3 5 9 2 8 0 1 6 9 8 2 6 1 7 3 5 4 2 9 3 1 8 6 4 7 5 1 6 8 5 7 4 9 3 2 5 4 7 2 3 9 6 8 1 3 2 4 8 9 1 5 6 7 8 1 9 7 6 5 2 4 3 7 5 6 3 4 2 1 9 8 6 7 1 4 5 3 8 2 9 4 3 5 9 2 8 0 1 6 9 8 2 6 0 7 3 5 4 2 9 3 1 0 6 4 7 5 1 6 8 5 7 4 9 3 2 5 4 7 2 3 9 6 8 1 2 5 0 0 0 9 0 4 0 4 0 7 1 0 3 0 0 6 8 0 3 4 0 7 5 9 0 3 0 8 0 7 0 0 6 9 0 1 0 3 0 2 4 0 0 5 0 4 9 0 6 0 8 3 9 0 6 0 3 0 7 0 8 0 3 0 6 0 8 0 1 0 1 0 2 0 9 0 6 0 4 1 0 8 7 3 6 5 0 0 0 7 0 0 1 5 0 3 0 0 3 6 0 9 8 7 1 4 2 0 7 5 6 3 0 8 0 0 0 1 8 0 7 3 0 9 3 8 5 9 4 1 0 6 0 0 5 0 6 0 9 1 2 0 7 0 9 0 5 0 6 0 0 6 2 0 1 8 0 9 7 5 */ public class Shudo { static boolean log=false; static int step=0; public static void main(String[] args) { Scanner sc=new Scanner(System.in); //1.接收数据进来,0为需要填写的数据 Chess chesses[][]=new Chess[9][9]; for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ Chess c=new Chess(); c.setPx(i); c.setPy(j); c.setNum(sc.nextInt()); if(c.getNum()==0){ step++; } chesses[i][j]=c; } }//数据接收完毕 while(step>0){ chesses=guessChess(chesses);//先计算出所有未确定格子的可能数字 chesses=oneChooseLess(chesses);//运用唯一选择法进行扫描 } if(isSloveRight(chesses)){ System.out.println("Slove right!The answer is blow."); for(int i=0;i<9;i++){ System.out.println(" "); for(int j=0;j<9;j++){ Chess chess=chesses[i][j]; System.out.print(" "+chess.getNum()); } } }else{ System.out.print("Slove error!"); } sc.close(); } public static boolean isSloveRight(Chess[][] chesses){//检查是否有重复的数据,以确认是否问题正确解决,应先检查是否有0 if(!isSlove(chesses)){ return false;//都没有解决呢,不要来混答案 } for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ Chess chess=chesses[i][j]; for(int x=0;x<9;x++){ if(x!=i && chesses[x][j].getNum()==chesses[i][j].getNum()){//同一列有相同的数 return false; } if(x!=j && chesses[i][x].getNum()==chesses[i][j].getNum()){//同一行有相同的数 return false; } } int startx=i/3*3; int starty=j/3*3; for(int m=startx;m<startx+3;m++){ for(int n=starty;n<starty+3;n++){ if(i!=m && j!=n && chesses[m][n].getNum()==chesses[i][j].getNum()){//同一个圈有相同的数 return false; } } } } } return true; } public static boolean isSlove(Chess[][] chesses){//检查是否还有0,以确认是否完成问题解决 for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ Chess chess=chesses[i][j]; if(chess.getNum()==0){//还有没有计算出的数字 return false; } } } return true; } public static Chess[][] oneChooseLess(Chess[][] chesses){//只有一个候选数字,那数字就应该是这个数字 for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ Chess chess=chesses[i][j]; if(log){ System.out.println(i+","+j+":"); } if(chess.getChooseNum()!=null && chess.getChooseNum().size()==1){ if(log){ System.out.println("--------------------------------------"); } chess.setNum( chess.getChooseNum().get(0)); step--;//确定一个,减去一个 chesses=guessChess(chesses); } } } return chesses; } public static Chess[][] guessChess(Chess[][] chesses){//重新生成数独中每个未知棋子的可能棋子,当有任意棋子被新确定时,都应该执行此方法,以更新新局面 for(int m=0;m<9;m++){ for(int n=0;n<9;n++){ Chess chess=chesses[m][n]; //chess=guessChess(chess,chesses); List<Integer> sList=new ArrayList<Integer>(); int px=chess.getPx(); int py=chess.getPy(); int num=chess.getNum(); if(num==0){ if(log){ System.out.println("["+px+","+py+"]"); } for(int i=0;i<9;i++){//行和列中已经有的数字,不应该被包含了 Chess c1=chesses[px][i];//一行 if(c1.getNum()!=0){ sList.add(c1.getNum());//行中已经有的数 if(log){ System.out.println("["+px+","+i+"]添加了: "+c1.getNum()); } } Chess c2=chesses[i][py];//一列 if(c2.getNum()!=0){ sList.add(c2.getNum());//列中已经有的数 if(log){ System.out.println("["+i+","+py+"]添加了: "+c2.getNum()); } } } //圈中已经有的数字,也不应该被包含了 int startx=px/3*3; int starty=py/3*3; for(int i=startx;i<startx+3;i++){ for(int j=starty;j<starty+3;j++){ if(chesses[i][j].getNum()!=0){ sList.add(chesses[i][j].getNum()); } } } List<Integer> mList=new ArrayList<Integer>(); mList.add(1); mList.add(2); mList.add(3); mList.add(4); mList.add(5); mList.add(6); mList.add(7); mList.add(8); mList.add(9); List<Integer> rList=subList(mList,sList); if(log){ System.out.print("["+m+","+n+"]可能的数字: "); for (Integer rc : rList) { System.out.print(" "+rc); } System.out.println(" "); } chess.setChooseNum(rList); } } } return chesses;// } //mList是所有的,sList是部分数据,返回未包含的数据 public static List<Integer> subList(List<Integer> mList ,List<Integer> sList){ List<Integer> rList=new ArrayList<Integer>(); for (Integer mint : mList) { boolean has=false; for (Integer sint : sList) { if(sint.intValue()==mint.intValue() && sint!=0){ has=true; break; } } if(!has){ rList.add(mint); } } return rList; } } class Chess{ int px;//第几列 int py;//第几行 int num;//0为未确定 List<Integer> chooseNum;//可能是哪几个数字 public int getPx() { return px; } public void setPx(int px) { this.px = px; } public int getPy() { return py; } public void setPy(int py) { this.py = py; } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public List<Integer> getChooseNum() { return chooseNum; } public void setChooseNum(List<Integer> chooseNum) { this.chooseNum = chooseNum; } }