前言

周末两天,闲来无事,于是花了半天把自己很久就想研究的数独求解进行了算法实现。

初级玩法

首先看一下数独

屏幕快照 2018-03-25 下午6.30.52.png

数独规则

数独的规则比较简单:

每一行包括了1到9的数字,并且不能重复。

每一列包括了1到9的数字,并且不能重复。

每一组包括了1到9的数字,并且不能重复。

玩数独求解的流程

步骤一:从上到下,从左到右选择一个空单元。

步骤二: 根据这个单元所在的行、列、组,求出这个单元可能的解。

步骤三:随机抽取一个未论证的解作为单元的解进行填入,进行步骤一。

步骤四:如果步骤三中这个单元的所有未论证的解为空,则说明上一次随机填入有误。机型步骤五。

步骤五:退到上一个单元,将上一次随机填入解从未论证随机解中删除,进行步骤三。

步骤六:如果步骤二中这个单元的所有可能解为空,则说明上一次随机填入有误,进行步骤五。

步骤七:如果发现已经无法选择单元,即单元已经填满,说明完成解数独。

流程图:

shuduprocess.jpg

总体而言,整个过程是一个选择空单元,求合适解,选择未论证解,论证,论证之后再返回的过程。

代码实现

算法的实现步骤

输入

获取一个大小为81的范围为0-9的整型数组,0代表空。

新建一个9*9的二维单元结点数组,每个节点保存节点的位置,并将整形数组的值传给节点。

新建9个列的节点数组集合,9个行的节点数组集合,9个组的节点数组集合。每个节点保存保存所在列的节点数组集合,所在行的节点数组结合,所在组的节点数组结合。

输入代码

private void initData(char[] charArray) {

//新建各个节点对应步骤二

soduNodes = new SoduNode[9][9];

for (int i = 0; i < 9; i++) {

for (int k = 0; k < 9; k++) {

SoduNode soduNode = new SoduNode();

soduNode.value=charArray[i*9+k]-'0';

soduNode.xPosition=k;

soduNode.yPosition=i;

soduNodes[i][k]=soduNode;

}

}

//每个节点保存保存所在列的节点集合,所在行的节点集合,所在组的结合。对应步骤三

for(int i=0 ;i<9;i++){

SoduNode [] listNode=new SoduNode[9];

for(int k=0;k<9;k++){

listNode[k]=soduNodes[i][k];

soduNodes[i][k].listNode=listNode;

}

System.out.println("listNode:"+SoduNode.getNodesValue(listNode));

}

for(int i=0 ;i<9;i++){

SoduNode [] rowNode=new SoduNode[9];

for(int k=0;k<9;k++){

rowNode[k]=soduNodes[k][i];

soduNodes[k][i].rowNode=rowNode;

}

System.out.println("rowNode:"+SoduNode.getNodesValue(rowNode));

}

for(int i=0;i<=2;i++){

for(int k=0;k<=2;k++){

SoduNode [] groupNode=new SoduNode[9];

int index=0;

int middlex=3*i+1;

int middley=3*k+1;

for(int j=-1;j<=1;j++){

for(int l=-1;l<=1;l++){

groupNode[index]=soduNodes[middlex+j][middley+l];

soduNodes[middlex+j][middley+l].groupNode=groupNode;

index++;

}

}

System.out.println("groupNode:"+SoduNode.getNodesValue(groupNode));

}

}

}

求解

代码求解过程与玩数独的流程基本一致:

核心代码

//对应步骤一

private boolean getNextNodeAndCheck() {

SoduNode lastNullNode = getNextNullNode(); //步骤二

if(lastNullNode==null){

return true;

} //对应步骤七

Integer[] suitValue = lastNullNode.getSuitValue();

if(suitValue==null||suitValue.length==0){

System.out.println("no have suitable value");

return false;

}//对应步骤六

for(int i=0;i

lastNullNode.value=suitValue[I];//步骤三

//对应步骤一

if(getNextNodeAndCheck()){

return true;

}

}

return false;//所有可能解都已经论证完,无需论证解,对应步骤四

}

获取可能解的过程

Integer[] getSuitValue() {

TreeSet notSuits = new TreeSet<>();

TreeSet allValue= new TreeSet();

for (int i = 0; i <= 8; i++) {

if (listNode[i].value != 0) {

notSuits.add(listNode[i].value);

}

if (rowNode[i].value != 0) {

notSuits.add(rowNode[i].value);

}

if (groupNode[i].value != 0) {

notSuits.add(groupNode[i].value);

}

allValue.add(allChar[i]);

}

int notSuitSize = notSuits.size();

if (notSuitSize == 9) {

return null;

}

allValue.removeAll(notSuits);

System.out.println("allValue :" + getTreeValue(allValue));

Integer[]suitValue=new Integer[allValue.size()];

Iterator iterator = allValue.iterator();

int suitValueIndex=0;

while(iterator.hasNext()){

suitValue[suitValueIndex]=iterator.next();

suitValueIndex++;

}

System.out.println("suitValue size:"+suitValue.length+" value:"+getSuitsValue(suitValue));

return suitValue;

}

获取可能解的逻辑为

1.获取节点所在列、行、组所有存在的值的集合

2.将一个1到9的集合减掉存在值的集合即为可能解

运行

将上图数独求解

请输入81个数字代表数独:/n

009100000040078023600402001032680057895000030064310000407863915008590762956721040

initdata is :

0 0 9 1 0 0 0 0 0

0 4 0 0 7 8 0 2 3

6 0 0 4 0 2 0 0 1

0 3 2 6 8 0 0 5 7

8 9 5 0 0 0 0 3 0

0 6 4 3 1 0 0 0 0

4 0 7 8 6 3 9 1 5

0 0 8 5 9 0 7 6 2

9 5 6 7 2 1 0 4 0

resut is :

2 8 9 1 3 6 5 7 4

5 4 1 9 7 8 6 2 3

6 7 3 4 5 2 8 9 1

1 3 2 6 8 9 4 5 7

8 9 5 2 4 7 1 3 6

7 6 4 3 1 5 2 8 9

4 2 7 8 6 3 9 1 5

3 1 8 5 9 4 7 6 2

9 5 6 7 2 1 3 4 8

联系我

数独问题流程图_数独求解算法相关推荐

  1. 数独问题流程图_数独游戏的难度等级分析及求解算法研究

    2 数独难度等级 数独游戏发展至今, 在数独爱好者的积极探索下, 求解数独的算法众多, 有 矩形顶点删减法.关键数删减法等 [7] .解答一道数独问题是一种或多种方法相互 结合, 为了使玩家能循环渐进 ...

  2. 数独问题流程图_软件工程基础大项目——数独问题

    Github项目地址:https://github.com/WX78yyj/sudoku(由于自己有不爱命名的坏习惯,所以忘记命名了,结果提交的文件名称是未命名3,发现还改不了,郁闷) PSP2.1 ...

  3. 递归算法 流程图_什么是算法?如何学习算法?算法入门

    转自:http://www.cnblogs.com/jiangwz/p/7765694.html 算法 什么是算法? 有一个很著名的公式 "程序=数据结构+算法". 曾经跟朋友吃饭 ...

  4. 递归算法 流程图_什么是算法?如何学习算法?算法入门的学习路径

    什么是算法? 有一个很著名的公式 "程序=数据结构+算法". 曾经跟朋友吃饭的时候我问他什么是算法,他说算法嘛,就是一套方法,需要的时候拿过来,套用就可以,我吐槽他,他说的是小学数 ...

  5. raptor五个数排序流程图_数据结构与算法(一):排序(上)

    做这个系列一是记录自己的学习过程,二是整合目前我所接触的比较好的资料,给出最直观,最通俗的算法解释 总体概况 十大排序算法:(比较排序):冒泡.选择.插入.归并.快速.希尔.堆排序 基数排序.桶排序. ...

  6. python数独游戏源代码_数独源程序py

    #!/usr/bin/python #coding=utf-8 #sudoku # import random class sudoku(object): def __init__(self): se ...

  7. 选择排序算法流程图_常用排序算法之选择排序

    前两天给大家分享了冒泡排序和插入排序(没关注的同学,可以关注后查看历史消息),今天继续给大家分享另一种常用的排序算法--选择排序. 选择排序 选择排序和插入排序很相似,也区分已排序区间和未排序区间,选 ...

  8. 数独求解算法_我如何回到一个老问题,终于写了一个数独求解算法

    数独求解算法 by Ali Spittel 通过Ali Spittel 我如何回到一个老问题,终于写了一个数独求解算法 (How I came back to an old problem and f ...

  9. java数独流程图_九宫格数独游戏C语言解法

    最近几天深圳一直下雨,一个人闷在屋里很是无聊,偶然打开一个小游戏网站看到了我的最爱--九宫格数独游戏.共有1-5五个难度级别,像我这种资深玩家其他难度就不用考虑了,冲着难度5的题目就去了,结果做地汗流 ...

  10. python数独伪代码回溯法_数独 #回溯算法 #CTF

    1. intro:巅峰极客的一道逆向 刷巅峰极客2020里的rev题fu!kpy,复杂得不行但是看到if d[1][0] != '8' or d[1][7] != '2'和if check(h1) ! ...

最新文章

  1. 链mysql_mysql 版本链机制 readView
  2. mysql用if判断关联的表_mysql表连接,子查询以及if判断
  3. 机器学习实战(用Scikit-learn和TensorFlow进行机器学习)(八)
  4. SAP CRM settype的创建,背后发生了什么
  5. 关于node-sass和sass-loader安装上去的时候的时候报错的问题
  6. git add 命令的一个习惯用法:逐个挑选改动
  7. vc读取北通手柄按键_《噬血代码》手柄怎么操作 北通手柄按键功能详解
  8. I have to mention the search function at the
  9. abb机器人写字程序实例_abb机器人程序实例
  10. Windows2003 WINS 服务
  11. Mobileye/博世/大陆智驾份额「持续下滑」,本土供应商「起势」
  12. imac 蓝牙机械键盘_最好的蓝牙机械键盘
  13. 联想台式计算机 不启动u盘,联想电脑不能u盘启动怎么办
  14. 【数字图像处理 8】形态学图像处理
  15. 微信小程序怎么获取到data数据?
  16. mysql数据库熔断_服务熔断
  17. win7触摸板怎么关闭_笔记本fn键失灵怎么办?
  18. 高三学生早恋怎么处理?家长该怎么做?
  19. onedrive登陆以后是白板,我下载了onedrive以后,安装到登陆界面,输入账号,提示:我们的系统中没有 - Microsoft Community...
  20. 2011年11月校园招聘JAVA面试题整理

热门文章

  1. java 客户端调用 Tuxedo中间件
  2. live555传输实时h264视频流和mp3音频流
  3. [VB.NET]请教一个如何对姓名进行同音字查询?
  4. 【数学建模】相关软件
  5. adobe reader XI 打开后闪退(或过几秒后自动退出)【终极解决方案】
  6. 模拟集成电路设计基础知识(二):MOS管二级效应及其小信号等效
  7. 虚拟机xp系统联网问题
  8. iphone java模拟器_电脑java模拟器 模拟器游戏
  9. linux系统开机grub命令修复方法,linux系统GRUB修复
  10. [vue] 混入+替换对应文字实现简繁切换