`
zhjx19892008
  • 浏览: 989 次
  • 性别: Icon_minigender_1
  • 来自: 南京
最近访客 更多访客>>
社区版块
存档分类
最新评论

用程序解数独,发现数独是个好东西,让我收获颇多

阅读更多
   最近在本站看到某篇关于解数独的程序的博客,于是下载后尝试了下,发现有些数独是可以解的,但当我把下面这个数独放进去后,它不能够给我解出来:

{8,0,0,0,0,0,0,0,0},
{0,0,3,6,0,0,0,0,0},
{0,7,0,0,9,0,2,0,0},
{0,5,0,0,0,7,0,0,0},
{0,0,0,0,4,5,7,0,0},
{0,0,0,1,0,0,0,3,0},
{0,0,1,0,0,0,0,6,8},
{0,0,8,5,0,0,0,1,0},
{0,9,0,0,0,0,4,0,0},

   我并没有去看他的算法是什么样的,索性就直接自己重新写了个。在对fillNumber()方法的实现过程中对于嵌套调用让我收获颇多,深刻体会到了JAVA的传值问题。
   现在把代码贴出与大家共享,请多多指正!

import java.util.ArrayList;
import java.util.List;

public class Sudoku {
	
	int[][] originalSudokuArray = null;
	private static int[] oneToNine = {1,2,3,4,5,6,7,8,9};	
	private List<int[][]> collector = new ArrayList<int[][]>();
	
	public Sudoku(int[][] sudokuArray){
		this.originalSudokuArray = sudokuArray;
	}
	
	private void solveSudoku(){
		fillNumber(originalSudokuArray,0,0);
		printSudokuArray();
	}
	
	private void fillNumber(int[][] sudokuArray,int rowPosition,int colPosition){
		for(int i=rowPosition;i<9;i++){
			for(int j=0;j<9;j++){				
				if(sudokuArray[i][j]==0){
					int[][] newSudokuArray = new int[9][9];
					for(int number:oneToNine){//
						if(numberIsLegal(sudokuArray,number,i,j)){
							newSudokuArray = valueDeliver(sudokuArray);
							newSudokuArray[i][j] = number;						
							if(hasNullBox(newSudokuArray)){								
								fillNumber(newSudokuArray,i,j);
							}else{
								collector.add(newSudokuArray);
								return;								
							}							
						}						
					}
					if(newSudokuArray[i][j]==0){
						sudokuArray[rowPosition][colPosition] = 0;
					}
					return;
				}
			}
		}
		return;
	}	
	
	private int[][] valueDeliver(int[][] sudokuArray){		
		int[][] newArray = new int[sudokuArray.length][sudokuArray[0].length];
		for(int i=0,len=sudokuArray.length;i<len;i++){
			for(int j=0,len1=sudokuArray[0].length;j<len1;j++){
				newArray[i][j] = sudokuArray[i][j];
			}
		}
		return newArray;
	}

	
	private boolean numberIsLegal(int[][] sudokuArray,int number,int rowPosition,int colPosition){		
		boolean legal = true;				
	
		//水平
		for(int i=0;i<9;i++){
			if(sudokuArray[rowPosition][i]==0) continue;
			if(sudokuArray[rowPosition][i]==number){
				legal = false;
			}
		}
		//垂直
		for(int i=0;i<9;i++){
			if(sudokuArray[i][colPosition]==0) continue;
			if(sudokuArray[i][colPosition]==number){
				legal = false;
			}
		}
		//九格
		int boxRowStart = (rowPosition/3)*3;
		int boxColStart = (colPosition/3)*3;
		for(int i=boxRowStart;i<boxRowStart+3;i++){
			for(int j=boxColStart;j<boxColStart+3;j++){
				if(sudokuArray[i][j]==0) continue;
				if(sudokuArray[i][j]==number){
					legal = false;
				}
			}
		}
		return legal;
	}
		private boolean hasNullBox(int[][] sudokuArray){
			boolean nullFlag = false;
			for(int i=0;i<9;i++){
				for(int j=0;j<9;j++){	
					if(sudokuArray[i][j]==0){
						nullFlag = true;
					}
				}
			}
			return nullFlag;
		}
	
	private void printSudokuArray(){		
		for(int[][] intArray:collector){
			for(int i=0;i<9;i++){
				for(int j=0;j<9;j++){
					System.out.print(intArray[i][j]+" ");
				}
				System.out.println();
			}	
			System.out.println("---------------------------------");
		}
		System.out.println("总共"+collector.size()+"个解!");
	}
	
	
		
	public static void main(String[] args){
		int[][] originalArray = {
				{8,0,0,0,0,0,0,0,0},
				{0,0,0,6,0,0,0,0,0},
				{0,7,0,0,9,0,2,0,0},
				{0,5,0,0,0,7,0,0,0},
				{0,0,0,0,4,5,7,0,0},
				{0,0,0,1,0,0,0,3,0},
				{0,0,1,0,0,0,0,6,8},
				{0,0,8,5,0,0,0,1,0},
				{0,9,0,0,0,0,4,0,0},
			};
		Sudoku sdk = new Sudoku(originalArray);
		sdk.solveSudoku();		
	}
}

//测试数据:

//4个解
//{0,0,0,0,0,0,0,0,0},
//{0,0,0,0,0,1,0,0,3},
//{0,0,0,9,3,2,6,8,1},
//{6,5,0,2,9,0,7,3,8},
//{7,3,0,8,0,5,4,6,9},
//{9,0,0,0,7,3,5,1,2},
//{2,1,5,3,4,7,8,9,6},
//{4,6,8,1,2,0,0,0,7},
//{3,7,9,5,8,6,1,0,0},

//1个
//{1,0,0,0,6,0,0,0,7},
//{0,9,6,7,0,1,0,4,0},
//{0,4,7,0,3,0,6,8,0},
//{6,5,0,2,0,4,7,0,8},
//{0,0,2,0,0,5,4,6,0},
//{0,8,4,6,0,3,0,0,2},
//{0,1,5,0,4,0,8,9,0},
//{4,0,8,1,0,9,3,0,5},
//{3,7,0,5,0,6,0,2,4},

//1个
//{8,0,0,0,0,0,0,0,0},
//{0,0,3,6,0,0,0,0,0},
//{0,7,0,0,9,0,2,0,0},
//{0,5,0,0,0,7,0,0,0},
//{0,0,0,0,4,5,7,0,0},
//{0,0,0,1,0,0,0,3,0},
//{0,0,1,0,0,0,0,6,8},
//{0,0,8,5,0,0,0,1,0},
//{0,9,0,0,0,0,4,0,0},

//比上面只少了一个数字,1634个解
//{8,0,0,0,0,0,0,0,0},
//{0,0,0,6,0,0,0,0,0},
//{0,7,0,0,9,0,2,0,0},
//{0,5,0,0,0,7,0,0,0},
//{0,0,0,0,4,5,7,0,0},
//{0,0,0,1,0,0,0,3,0},
//{0,0,1,0,0,0,0,6,8},
//{0,0,8,5,0,0,0,1,0},
//{0,9,0,0,0,0,4,0,0},

分享到:
评论

相关推荐

    su'do'ku_sudoku_MATLAB解数独_matlab_数独游戏_数独_源码

    标签中的"数独 MATLAB解数独"表明了这个项目的主要焦点,而"matlab 数独游戏"则暗示了这个MATLAB程序可能设计成互动游戏形式,允许用户输入自定义的数独盘面或随机生成数独题目。 总的来说,这个压缩包提供了使用...

    python实现解数独程序代码

    下面就记录一下我写解数独程序的一些思路和心得。 一.数独游戏的基本解决方法 编程笼统的来说,就是个方法论。不论什么程序,都必须将问题的解决过程分解成计算机可以实现的若干个简单方法。俗话说,大道至简。对于...

    c语言回溯解数独程序

    通过以上步骤,我们可以编写出一个简单的C语言回溯解数独程序。这种程序不仅易于理解和实现,而且由于C语言的效率,其运行速度也相当不错。对于学习算法和数据结构的学生来说,这是一个很好的练习项目,有助于提升...

    一个解数独的程序

    标题中的“一个解数独的程序”指的是一个用于自动解决数独谜题的软件或算法。数独是一种基于逻辑的数字填充游戏,玩家需要在9x9的网格中填入数字,使得每行、每列以及每个3x3的小宫格内的数字都从1到9不重复。解数独...

    解数独程序

    总的来说,解数独程序的开发涉及了算法设计、数据结构应用以及逻辑推理等多个计算机科学领域的知识,是学习和实践编程思维的好项目。通过这个程序,不仅可以提升编程能力,还能加深对约束满足问题解决策略的理解。

    Matlab解数独的程序

    标题中的"Matlab解数独的程序"指的是使用MATLAB语言编写的算法,该算法可以自动解决数独难题。这样的程序通常会采用回溯法或深度优先搜索(DFS)策略,通过递归地填充空格并检查每一步的合法性来寻找唯一的解决方案...

    解数独 数独游戏 DFS搜索

    解数独程序源码

    MATLAB 解数独

    本文将深入探讨如何使用MATLAB来编写一个解数独的程序,以及递归调用在其中的作用。 首先,我们要理解数独的基本规则。数独盘面是一个9x9的网格,分为9个3x3的小宫格,每个宫格、每一行、每一列都必须包含数字1到9...

    java解数独

    标题中的“Java解数独”指的是...总的来说,Java解数独项目是一个很好的实践案例,它涵盖了数据结构、算法、递归和错误处理等多个编程基础概念。通过这个项目,你可以提升解决问题的能力,并对Java编程有更深入的理解。

    解数独C程序

    在给定的标题“解数独C程序”中,我们可以理解这是一份使用C语言编写的程序,它的目的是解决数独问题。 C语言是一种基础且高效的编程语言,常用于系统级编程和开发嵌入式系统。在这个项目中,我们可能会看到如何...

    唯一解数独 生成算法 java

    唯一解数独指的是生成的数独谜题有且只有一个解决方案。在Java编程语言中实现唯一解数独的生成算法是一项挑战,涉及到深度优先搜索(DFS)、回溯等技术。 ### 数独生成算法原理 1. **挖洞思想**:数独生成过程中,...

    C++解数独问题

    本项目涉及的主题是“C++解数独问题”,它利用了算法中的回溯法来解决经典的逻辑难题——数独。数独是一种基于数字填充的逻辑游戏,玩家需要在9x9的网格中填入数字,使得每一行、每一列以及每个3x3的子宫(九宫格)...

    回溯法解决数独问题-2.docx

    本文主要介绍了使用 MATLAB 解数独问题的回溯法解决方法。数独是一种非常流行的智力游戏,需要填充 9x9 的方格,使每一行、每一列、以及所分出的 9 个主要 3x3 区块,包含 1 到 9 所有的数字。解数独的挑战在于找到...

    C语言解数独程序:贪心+递归

    在解数独的过程中,贪心算法可以用于填充那些只有一种可能答案的单元格,即当某单元格所在的行、列和小宫格中只剩下一个未使用的数字时,我们可以直接填入。 然而,仅靠贪心算法不能解决所有数独问题,因为有些情况...

    求解多解数独的C语言代码

    并非所有数独均只有一个解 该程序将为求解多解数独 欢迎各位高手赐教提高其效率

    回溯法解数独问题

    ### 回溯法解数独问题 #### 一、数独简介 数独是一种起源于18世纪瑞士的数字逻辑游戏,它不仅是一项娱乐活动,也是一种极佳的智力锻炼工具。标准的数独由9个3×3的小方格组成的大九宫格构成,共计81个格子。游戏...

    C#数独破解程序

    本篇文章将围绕一个使用C#语言编写的数独破解程序进行深入探讨。 首先,我们要理解数独的基本规则。数独是一种9x9的网格,分为9个3x3的小宫格,每个宫格内填入数字1到9,要求每行、每列和每个小宫格内的数字都必须...

    解数独(九宫格)的程序

    "解数独(九宫格)的程序"显然就是一种能自动解决数独谜题的软件。 程序设计的核心算法通常基于回溯法或深度优先搜索(DFS),有时会结合一些启发式策略以提高效率。回溯法是一种试探性的解决问题方法,当尝试填充...

    解数独工具

    "解数独工具.exe"是这个程序的执行文件,用户可以通过双击运行来启动工具。而"使用说明.txt"则包含了如何操作和使用该工具的详细步骤和提示,包括如何加载数独谜题、如何启用自动解决功能、如何查看解题步骤等。对于...

Global site tag (gtag.js) - Google Analytics