java解数独_用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

for(int n=starty;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 sList=new ArrayList();

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

for(int j=starty;j

if(chesses[i][j].getNum()!=0){

sList.add(chesses[i][j].getNum());

}

}

}

List mList=new ArrayList();

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 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 subList(List mList ,List sList){

List rList=new ArrayList();

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 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 getChooseNum() {

return chooseNum;

}

public void setChooseNum(List chooseNum) {

this.chooseNum = chooseNum;

}

}

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2016-07-08 13:06

浏览 567

评论

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值