首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

一个求解数独的代码,哪位高手能给分析下

2012-03-21 
一个求解数独的代码,谁能给分析下?package Java.puzzlerimport static java.util.Arrays.*public class

一个求解数独的代码,谁能给分析下?
package Java.puzzler;  
import static java.util.Arrays.*;  
  
public class Puzzler{  
  public static final int SIZE =9;  
  private boolean[][] fixed =new boolean[SIZE][SIZE];  
  private int[][] number =new int[SIZE][SIZE];  
  public Puzzler(){  
  }  
  public Puzzler(int[][] p){  
  setPuzzler(p);  
  }  
  /**  
  * 用一个二维数组去设置该数独  
  * 注意:这个二维数组应该只包含0~9中的数字,为0时表示该处留空  
  * 该方法假设p的数据是合法的,不对其进行任何检查  
  */  
  public void setPuzzler(int[][] p){  
  for(int i=0;i<SIZE;i++)  
  for(int j=0;j<SIZE;j++){  
  if(p[i][j] ==0){  
  fixed[i][j] =false; //不固定
  number[i][j] =0; //将 0 装入number数组 
  } else{  
  number[i][j] =p[i][j]; //将用户输入数组装入number数组 
  fixed[i][j] =true; //固定
  }  
  }  
  }  
  /**  
  * 清除  
  */  
  public void clear(){  
  for(int n=0;n<SIZE;n++){  
  fill(fixed[n],false);  
  fill(number[n],0); //fill用法?
  }  
  return;  
  }  
  /**  
  * 位置i,j是否固定,如果固定表示该处的数字不能更改  
  */  
  public boolean isFixed(int i,int j){  
  return fixed[i][j]; //判断是否为空
  }  
  /**  
  * 得到位置i,j处的数字  
  */  
  public int getNumber(int i,int j){  
  return number[i][j];  
  }  
  /**  
  * 设置i,j处的数字.如果该处数字是固定的,将抛出异常  
  */  
  public void setNumber(int i,int j,int num){  
  if(num<0||num>9) throw new IllegalArgumentException("number is out of 0~9 :"+num);  
  if(isFixed(i,j)) throw new IllegalStateException("puzzler("+i+","+j+") is fixed");  
  number[i][j] =num; //将 num 装入number数组
  }  

============================================================================================

import Java.puzzler.*;  
  
/**  
 * 求解Sodoku Puzzler的工具类  
 * @author Eastsun  
 */  
public class Solver{  
  private static final int SIZE = Puzzler.SIZE;  
  private Solver(){  
  }  
  public static boolean solve(Puzzler p){  
  int[][] num =new int[SIZE][SIZE];  
  boolean[][] rFlags =new boolean[SIZE][SIZE+1], //SIZE+1代表用户数字t
  cFlags =new boolean[SIZE][SIZE+1],  
  zFlags =new boolean[SIZE][SIZE+1];  
  for(int r=0;r<SIZE;r++)  
  for(int c=0;c<SIZE;c++)  
  if(p.isFixed(r,c)){ // 排除 0
  int t =p.getNumber(r,c); //得到r,c处的用户数字t
  num[r][c] =t; //并装入num数组
  rFlags[r][t] =true; //r-t
  cFlags[c][t] =true; //c-t
  zFlags[r/3*3+c/3][t] =true; //区域036 147 258


  }  
  int r =0,c =0; //由8清零  
  outLoop:  
  for(;;){//&#  
  if(p.isFixed(r,c)){ //固定数字&#if(p.isFixed())
  c ++;  
  if(c>=SIZE){  
  c =0;  
  r ++; //c加完后r加
  if(r>=SIZE) break outLoop; //r也加完后退出,此时为表格末尾 
  }  
  continue outLoop; //c=c+1后继续判断r,c是否固定 ,不固定(0)则向下运行 
  } //&#if(p.isFixed())  
  int t =SIZE;  
  for(c++;;){//&#  
  if(t>=SIZE){  
  c --;  
  if(c==-1){//c=-1  
  c =SIZE -1;  
  r --;  
  if(r==-1) break outLoop;  
  }  
  if(p.isFixed(r,c)) continue; // r,c固定,继续for(c++;;)?
  t =num[r][c];  
  if(t!=0){  
  rFlags[r][t] =false;  
  cFlags[c][t] =false;  
  zFlags[r/3*3+c/3][t] =false;  
  num[r][c] =0;  
  }  
  } else{  
  t ++;  
  if(!(rFlags[r][t]||  
  cFlags[c][t]||  
  zFlags[r/3*3+c/3][t])  
  ) break;  
  }  
  }//&#for(c++;;);  
  num[r][c] =t;  
  rFlags[r][t] =true;  
  cFlags[c][t] =true;  
  zFlags[r/3*3+c/3][t] =true;  
  c ++;  
  if(c>=SIZE){  
  c =0;  
  r ++;  
  if(r>=SIZE) break outLoop;  
  }  
  }  
  if(r<0) return false;  
  /* for(r=0;r<SIZE;r++)  
  for(c=0;c<SIZE;c++)  
  if(!p.isFixed(r,c)) p.setNumber(r,c,num[r][c]);*/  
  return true;  
  }  
  //test  
  public static void main(String[] args){  
  //解一个全空的数独  
  //Puzzler p =new Puzzler();  
  //int[][] p1=new int[9][9]; 
  //int[][] p1={{0,0,0,0,0,0,0,0,0,0,5,3,1,6,2,0,0,0,0,0,7,0,0,0,2,0,4,5,0,0,4,0,0,3,9,0,0,3,0,0,0,7,0,0,5,6,1,0,0,5,0,0,4,0,7,0,1,0,0,9,0,3,0,0,2,9,0,7,0,0,0,0,0,4,0,0,8,0,0,0,2};
  int[][] p1={{0,0,0,0,0,0,0,0,0},
{0,5,3,1,6,2,0,0,0,},
{0,0,7,0,0,0,2,0,4},
{5,0,0,4,0,0,3,9,0},
{0,3,0,0,0,7,0,0,5},
{6,1,0,0,5,0,0,4,0},
{7,0,1,0,0,9,0,3,0},
{0,2,9,0,7,0,0,0,0},
{0,4,0,0,8,0,0,0,2}};
Puzzler p =new Puzzler(p1);  
  System.out.println(solve(p));  
  for(int r =0;r<SIZE;r++){  
  for(int c=0;c<SIZE;c++) System.out.print(p.getNumber(r,c)+" ");  


  System.out.println();  
  }  
  }  





[解决办法]
fill方法呢?
[解决办法]
网上搜的?自己认真看看吧...
[解决办法]
学习了 现在还看不怎么懂
[解决办法]
还没学到,现在还看不怎么懂
[解决办法]
网上搜的?自己认真看看吧
[解决办法]
我看你都加了注释了,应该大致都了解吧
至于fill(number[n],0); //fill用法? 
将值0分配给number数组的每个元素,在java.util.Arrays里
不知道就查看API文档吧

热点排行