最近在本站看到某篇关于解数独的程序的博客,于是下载后尝试了下,发现有些数独是可以解的,但当我把下面这个数独放进去后,它不能够给我解出来:
{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},
分享到:
相关推荐
标签中的"数独 MATLAB解数独"表明了这个项目的主要焦点,而"matlab 数独游戏"则暗示了这个MATLAB程序可能设计成互动游戏形式,允许用户输入自定义的数独盘面或随机生成数独题目。 总的来说,这个压缩包提供了使用...
下面就记录一下我写解数独程序的一些思路和心得。 一.数独游戏的基本解决方法 编程笼统的来说,就是个方法论。不论什么程序,都必须将问题的解决过程分解成计算机可以实现的若干个简单方法。俗话说,大道至简。对于...
通过以上步骤,我们可以编写出一个简单的C语言回溯解数独程序。这种程序不仅易于理解和实现,而且由于C语言的效率,其运行速度也相当不错。对于学习算法和数据结构的学生来说,这是一个很好的练习项目,有助于提升...
标题中的“一个解数独的程序”指的是一个用于自动解决数独谜题的软件或算法。数独是一种基于逻辑的数字填充游戏,玩家需要在9x9的网格中填入数字,使得每行、每列以及每个3x3的小宫格内的数字都从1到9不重复。解数独...
总的来说,解数独程序的开发涉及了算法设计、数据结构应用以及逻辑推理等多个计算机科学领域的知识,是学习和实践编程思维的好项目。通过这个程序,不仅可以提升编程能力,还能加深对约束满足问题解决策略的理解。
标题中的"Matlab解数独的程序"指的是使用MATLAB语言编写的算法,该算法可以自动解决数独难题。这样的程序通常会采用回溯法或深度优先搜索(DFS)策略,通过递归地填充空格并检查每一步的合法性来寻找唯一的解决方案...
解数独程序源码
本文将深入探讨如何使用MATLAB来编写一个解数独的程序,以及递归调用在其中的作用。 首先,我们要理解数独的基本规则。数独盘面是一个9x9的网格,分为9个3x3的小宫格,每个宫格、每一行、每一列都必须包含数字1到9...
标题中的“Java解数独”指的是...总的来说,Java解数独项目是一个很好的实践案例,它涵盖了数据结构、算法、递归和错误处理等多个编程基础概念。通过这个项目,你可以提升解决问题的能力,并对Java编程有更深入的理解。
在给定的标题“解数独C程序”中,我们可以理解这是一份使用C语言编写的程序,它的目的是解决数独问题。 C语言是一种基础且高效的编程语言,常用于系统级编程和开发嵌入式系统。在这个项目中,我们可能会看到如何...
唯一解数独指的是生成的数独谜题有且只有一个解决方案。在Java编程语言中实现唯一解数独的生成算法是一项挑战,涉及到深度优先搜索(DFS)、回溯等技术。 ### 数独生成算法原理 1. **挖洞思想**:数独生成过程中,...
本项目涉及的主题是“C++解数独问题”,它利用了算法中的回溯法来解决经典的逻辑难题——数独。数独是一种基于数字填充的逻辑游戏,玩家需要在9x9的网格中填入数字,使得每一行、每一列以及每个3x3的子宫(九宫格)...
本文主要介绍了使用 MATLAB 解数独问题的回溯法解决方法。数独是一种非常流行的智力游戏,需要填充 9x9 的方格,使每一行、每一列、以及所分出的 9 个主要 3x3 区块,包含 1 到 9 所有的数字。解数独的挑战在于找到...
在解数独的过程中,贪心算法可以用于填充那些只有一种可能答案的单元格,即当某单元格所在的行、列和小宫格中只剩下一个未使用的数字时,我们可以直接填入。 然而,仅靠贪心算法不能解决所有数独问题,因为有些情况...
并非所有数独均只有一个解 该程序将为求解多解数独 欢迎各位高手赐教提高其效率
### 回溯法解数独问题 #### 一、数独简介 数独是一种起源于18世纪瑞士的数字逻辑游戏,它不仅是一项娱乐活动,也是一种极佳的智力锻炼工具。标准的数独由9个3×3的小方格组成的大九宫格构成,共计81个格子。游戏...
本篇文章将围绕一个使用C#语言编写的数独破解程序进行深入探讨。 首先,我们要理解数独的基本规则。数独是一种9x9的网格,分为9个3x3的小宫格,每个宫格内填入数字1到9,要求每行、每列和每个小宫格内的数字都必须...
"解数独(九宫格)的程序"显然就是一种能自动解决数独谜题的软件。 程序设计的核心算法通常基于回溯法或深度优先搜索(DFS),有时会结合一些启发式策略以提高效率。回溯法是一种试探性的解决问题方法,当尝试填充...
"解数独工具.exe"是这个程序的执行文件,用户可以通过双击运行来启动工具。而"使用说明.txt"则包含了如何操作和使用该工具的详细步骤和提示,包括如何加载数独谜题、如何启用自动解决功能、如何查看解题步骤等。对于...