• 数独游戏求解程序


    最近玩数独游戏,每行、每列、以及9宫格都包含1-9个数组。觉得这东西很适合用程序来求解。于是我就仿照中国象棋的暴力搜索算法(可参考我之前写的文章极大极小搜索算法),写了一个程序求解数独,直接贴代码了(以上传至github

    /**
     * 模仿象棋程序的搜索算法,写一个求解数独的程序
     * @author royhoo
     *
     */
    public class ShuDu {
    	private int[][] board;		// 数独矩阵
    	private int zeroNum;			// 缺失的数字个数
    	private int filledNum;	// 已填充的数字个数
    	public int[][] result;		// 填充后的最终结果
    	
    	public ShuDu(int[][] board){
    		this.board = board;
    		
    		zeroNum = getZeroNum();
    		filledNum = 0;
    		result = new int[9][9];
    	}
    	
    	/**
    	 * 计算缺失的数字个数
    	 * @return
    	 */
    	private int getZeroNum(){
    		int num = 0;
    		for(int i=0; i<9; i++){
    			for(int j=0; j<9; j++){
    				if(board[i][j] == 0){
    					num++;
    				}
    			}
    		}
    		
    		return num;
    	}
    	
    	/**
    	 * 递归调用,填充缺失的数组。如果填充完毕,返回-1.否则,返回0。
    	 */
    	public int search(){
    		for(int i=0; i<9; i++){
    			for(int j=0; j<9; j++){
    				if(board[i][j] > 0){
    					continue;
    				}
    				
    				int[] nums = getLegalNumbers(i, j);
    				for(int k=1; k<=9; k++){	// 这个for循环,类似于象棋中搜索了一层。
    					if(nums[k] > 0){
    						board[i][j] = k;
    						filledNum++;
    						if(filledNum >= zeroNum){
    							// 缺失数字全部填充完毕
    							copyResult();
    							return -1;
    						}
    						if(search() == -1){
    							return -1;
    						}
    						board[i][j] = 0;
    						filledNum--;
    					}
    				}
    				return 0;
    			}
    		}
    		
    		return 0;
    	}
    	
    	/**
    	 * 返回某位置可以填的数字
    	 */
    	private int[] getLegalNumbers(int i, int j){
    		int[] result = {0,1,1,1,1,1,1,1,1,1};
    		
    		// 保证第i行不重复
    		for(int k=0; k<9; k++){
    			if(board[i][k] > 0){
    				result[board[i][k]] = 0;
    			}
    		}
    		
    		// 保证第j列不重复
    		for(int k=0; k<9; k++){
    			if(board[k][j] > 0){
    				result[board[k][j]] = 0;
    			}
    		}
    		
    		// 保证9宫格不重复
    		for(int m=(i/3)*3; m<(i/3 + 1)*3; m++){
    			for(int n=(j/3)*3; n<(j/3 + 1)*3; n++){
    				if(board[m][n] > 0){
    					result[board[m][n]] = 0;
    				}
    			}
    		}
    		
    		return result;
    	}
    
    	private void copyResult(){
    		for(int i=0; i<9; i++){
    			for(int j=0; j<9; j++){
    				result[i][j] = board[i][j];
    			}
    		}
    	}
    	
    	public static void main(String[] args) {		
    		int[][] board = {
    				{3,5,0,9,0,0,6,0,0},
    				{0,0,6,0,0,0,0,0,0},
    				{4,2,0,5,0,0,0,9,0},
    				{5,0,0,6,0,4,0,2,0},
    				{0,1,0,2,8,0,3,0,0},
    				{0,0,2,0,9,5,0,0,4},
    				{0,0,3,0,2,0,5,0,8},
    				{0,4,0,0,1,0,9,0,6},
    				{0,0,0,0,0,0,0,1,0}
    		};
    		
    		ShuDu myShuDu = new ShuDu(board);
    		myShuDu.search();
    		int[][] result = myShuDu.result;
    		for(int i=0; i<9; i++){
    			String str = "";
    			for(int j=0; j<9; j++){
    				str = str + result[i][j] + ",";
    			}
    			System.out.println(str);
    		}
    	}
    
    }
  • 相关阅读:
    图灵机器人聊天api
    数据结构(七)之树
    Android批量图片载入经典系列——Volley框架实现多布局的新闻列表
    OCP试题解析之053-17 CONFIGURE CONTROLFILE AUTOBACKUP ON
    深入浅出理解排序算法之-堆排序
    【转】深入理解Android的startservice和bindservice--不错
    【转】Service Intent must be explicit的解决方法
    【转】Win7+Ubuntu12.04.1硬盘安装错误及解决方案----不错
    【转】Win7系统下安装Ubuntu12.04(EasyBCD硬盘安装)--不错
    【转】Ubuntu重装,直接进win7,不进linux的解决方案(添加Ubuntu启动菜单)
  • 原文地址:https://www.cnblogs.com/royhoo/p/6777888.html
Copyright © 2020-2023  润新知