关于《编程之美》中构造数独问题的小结

数独是一个很有意思的游戏,我以前玩过很多次,但一直没想过自己写一个。

读《编程之美》在构造数独这一小节中,书中给我们两个算法,这两个算法都是用来初步生成一张初始的数独图。 

回溯法和置换法。

对于第二个置换法,真的是超级简单,我看的时候简直惊呆了,还有这种操作,能这么简单。

简单讲一些两个算法:

回溯法:从第一个格子开始,在1-9数字中找一个合适放进去,然后下一个格子,再从1-9找合适的数字放进去,这时候要检验,检验这个格子中的数组是否和行,列,3*3小矩阵中数字有重复,如果找了一圈没找到合适的,就执行回溯,也就是回到上一个格子,把上一个格子里的数字换掉,然后再进行操作。这种操作方式对于学了算法的程序员来讲很容易想到。

置换法:先设置一个3*3矩阵。然后...


图中的{a,b,c,d,e,f,g,h,i}可以随机映射为{1,2,3,4,5,6,7,8,9},可以生成9!个不同的数独,但这不是所有的。

但是这种算法确实超级简单的。

关于实现:

public class Sudoku {

	//回溯法
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		Sudoku s = new Sudoku();
		s.sudoku();
	}
	
	public void sudoku(){
		int i,j;
		int[][] sudoku = new int[9][9];
		sudoku = init(sudoku);
		//回溯法
		int k ;
		k = 0;
		while (true){
			i = k / 9;
			j = k % 9;
			while (true){
				sudoku[i][j]++;
				if (sudoku[i][j] == 10){
					//全部测试一遍,失败,返回上一格
					sudoku[i][j] = 0;
					--k;
					break;
				}else if (check(sudoku,i,j)){
					//成功,下一格
					++k;
					break;
				}
			}
			if (k == 81){
				outSudoku(sudoku);
				return;
			}
		}
		
	}
	private int[][] init(int[][] sudoku){
		int i;
		int j;
		int temp;
		for (i = 0; i < 9; i++){
			for (j = 0 ; j < 9 ; j++){
				sudoku[i][j] = 0;
			}
		}
		for (i = 0 ; i < 9 ;i++){
			temp = (int)(Math.random()*81);
			sudoku[temp/9][temp%9] = i + 1;
		}
		return sudoku;
	}
	//检测这个值是否满足要求
	private boolean check(int[][] sudoku, int i, int j){
		int value = sudoku[i][j];
		int p, q;  
	    int m, n;  
	      
	    //检测行中有没有与之重复数值,有 则返回false
	    for (p = 0; p < 9; p++)  
	        if (p != i && sudoku[p][j] == value)  
	            return false; 
	    //检测列中有没有与之重复的数值,有 则返回false
	    for (p = 0; p < 9; p++)  
	        if (p !=j && sudoku[i][p] == value)  
	            return false;  
	  
	    p = i/3;  
	    q = j/3;  
	    //检测3*3 小矩阵
	    for (m = p*3; m < p*3+3; m++)  
	        for (n = q*3; n < q*3+3; n++)  
	            if (m != i && n != j && sudoku[m][n] == value)  
	                return false;  
	      
		return true;
	}
	//输出数独数组
	private void outSudoku(int[][] sudoku){
		int i;
		int j;
		for (i = 0; i < 9; i++){
			for (j = 0; j < 9 ; j++){
				System.out.print(sudoku[i][j] + " ");
			}
			System.out.println();
		}
	}
	

}

我参考http://blog.csdn.net/hustspy1990/article/details/7464698他的写了一版java的回溯法。


对于第二种算法置换法的数据结构,我想不直接用二维数组,而是用对象,一个对象代表一个3*3的小矩阵,这样写起来可能不会更易理解。【待验证】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值