用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;
}



}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值