用java解数独

自己写的,没解出来,搜到这个,没试过
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;
	}
	
	
	
}

猜你喜欢

转载自mushme.iteye.com/blog/2310033