JAVA数独解题(九):数链法(数串、垂直)

  • 说明
  • 图片
  • 算法代码
    • CalcEnum
    • SuLianVerticalCalc
    • SudoUtil
    • 测试数据
    • 输出结果
  • 总结
  • 代码详情

说明

参考文章:数独高级技巧:数串法的原理与应用详解(19年12月27日)
如下图所示,数字n在某一列中,只有两个空白格B1,B2(不在同宫中)存在,并且在行中也只有两个空白格B3,B4(不在同宫中)。并且两个端点都在某个宫中。则另外两个端点相交的其他宫的空白格B5,则没有数字n。

图片


算法代码

CalcEnum

在 绑定算法 中添加 属性

package com.suduku.calc.enums;import com.suduku.calc.*;
import lombok.AllArgsConstructor;
import lombok.Getter;import java.util.HashMap;
import java.util.Map;/*** 功能描述: 算法枚举 <br/>**/
@Getter
@AllArgsConstructor
public enum CalcEnum {/***/ONLY_NUM(OnlyNumCalc.class, "唯余法"),ONLY_BOX(OnlyBoxCalc.class, "摒除法"),GRID_XY(GridXYCalc.class, "单宫行列法"),SU_DUI(SuDuiCalc.class, "数对法"),X_WING(XwingCalc.class, "X-wing"),Y_WING(YwingCalc.class, "Y-wing"),XY_WING(XYwingCalc.class, "XY-wing"),YX_WING(YXwingCalc.class, "YX-wing"),XYZ_WING(XYZwingCalc.class, "XYZ-wing"),SU_LIAN_V(SuLianVerticalCalc.class, "数链垂直"), // 需要测试数据符合算法,调整顺序SU_LIAN_T(SuLianTrapezoidCalc.class, "数链梯形"),;private static final Map<Class<? extends AbstractCalc>, CalcEnum> CE_MAP = new HashMap<>(CalcEnum.values().length);static {for(CalcEnum ce : CalcEnum.values()) {CE_MAP.put(ce.getClazz(), ce);}}/*** 功能描述: 通过类,获取枚举 <br/>** @param clazz 类* @return "com.suduku.calc.enums.CalcEnum"*/public static CalcEnum indexOf(Class<? extends AbstractCalc> clazz) {return CE_MAP.get(clazz);}private final Class<? extends AbstractCalc> clazz;private final String name;}

SuLianVerticalCalc

package com.suduku.calc;import com.suduku.entity.Box;
import com.suduku.util.SudoUtil;import java.util.List;
import java.util.Map;/*** 数链-垂直(数字n在某一列中,只有两个空白格B1,B2(不在同宫中)存在,* 并且在行中也只有两个空白格B3,B4(不在同宫中)。并且两个端点都在某个宫中。* 则另外两个端点相交的其他宫的空白格B5,则没有数字n) <br/>** 测试数据:DataConstant.OTHER_SU_LIAN_V_01*/
public class SuLianVerticalCalc extends AbstractCalc {/***  1. 遍历所有数字*  2. 遍历所有列,获取只有两个候选值有数字n的空白格B1,B2,不能在同一宫中(可能存在多列)*  3. 遍历所有行,获取只有两个候选值有数字n的空白格B3,B4,不能在同一宫中(可能存在多行)*  4. 判断是否有两个顶点在同一个宫中。*  5. 如果存在有两个顶点在同一宫中,则另外两个顶点垂直相交的另一个点是空白格,则不包含数字n*/@OverrideBox solve() {// 遍历数字for(Integer n : Box.INIT_LIST) {// 遍历所有列for (Map.Entry<Integer, List<Box>> yEntry : getYMap().entrySet()) {// 获取B1,B2两个空白格List<Box> b12List = SudoUtil.findBoxByCList(yEntry.getValue(), n);if(SudoUtil.isTwoBox(b12List)) {// 遍历所有行,获取B3,B4两个空白格for (Map.Entry<Integer, List<Box>> xEntry : getXMap().entrySet()) {List<Box> b34List = SudoUtil.findBoxByCList(xEntry.getValue(), n);if(SudoUtil.isTwoBox(b34List)) {// B1B3相交同一宫中Box clearBox = intersectAndClear(b12List.get(1), b12List.get(0), b34List.get(0), b34List.get(1), n);if(clearBox != null) {return clearBox;}// B1B4相交同一宫中clearBox = intersectAndClear(b12List.get(1), b12List.get(0), b34List.get(1), b34List.get(0), n);if(clearBox != null) {return clearBox;}// B2B3相交同一宫中clearBox = intersectAndClear(b12List.get(0), b12List.get(1), b34List.get(0), b34List.get(1), n);if(clearBox != null) {return clearBox;}// B2B4相交同一宫中clearBox = intersectAndClear(b12List.get(0), b12List.get(1), b34List.get(1), b34List.get(0), n);if(clearBox != null) {return clearBox;}}}}}}return null;}/*** 功能描述: 相交与同一宫中,并且清理数字n <br/>* * @param b1 列非相交点* @param b2 列相交点* @param b3 行相交点* @param b4 行非相交点* @param n 候选值n* @return "com.suduku.entity.Box"*/private Box intersectAndClear(Box b1, Box b2, Box b3, Box b4, Integer n) {if(b2.getG() == b3.getG()) {Box box = getBoxByXY(b1.getX(), b4.getY());if(box != null && box.isBlank() && box.getCList().contains(n)) {getListener().sendMsg("清除数字%d\n", n);box.removeCList(n);return box;}}return null;}}

SudoUtil

    /*** 功能描述: 判断是否不在同一宫中的两个单元格 <br/>** @param bList 待判断单元格列表* @return "boolean"*/public static boolean isTwoBox(List<Box> bList) {return bList.size() == 2 && bList.get(0).getG() != bList.get(1).getG();}

测试数据

在 DataConstant 中添加

public static final String OTHER_X_WING_01 = "000300100500401090001028600090800001008017002010040800004085000300100040002634000";

输出结果

尝试【数链垂直  】
清除数字3
确认位置【行:1,列:6】  值为:【7】   候选值为:【】0 (3        ) 2 (         ) 9 (         ) |  1 (         ) 4 (         ){7}(         ) |  6 (         ) 8 (         ) 5 (         ) | 5 (         ) 1 (         ) 4 (         ) |  8 (         ) 6 (         ) 2 (         ) |  0 (37       ) 0 (39       ) 0 (379      ) | 6 (         ) 0 (378      ) 0 (38       ) |  0 (39       ) 0 (9        ) 5 (         ) |  2 (         ) 1 (         ) 4 (         ) | 1 (         ) 6 (         ) 7 (         ) |  5 (         ) 2 (         ) 8 (         ) |  0 (34       ) 0 (349      ) 0 (39       ) | 0 (48       ) 0 (348      ) 0 (358      ) |  7 (         ) 1 (         ) 9 (         ) |  0 (58       ) 2 (         ) 6 (         ) | 2 (         ) 9 (         ) 0 (58       ) |  6 (         ) 3 (         ) 4 (         ) |  0 (58       ) 7 (         ) 1 (         ) | 0 (37       ) 5 (         ) 2 (         ) |  4 (         ) 8 (         ) 1 (         ) |  9 (         ) 6 (         ) 0 (37       ) | 0 (49       ) 0 (34       ) 6 (         ) |  2 (         ) 0 (79       ) 0 (3        ) |  1 (         ) 5 (         ) 8 (         ) | 0 (89       ) 0 (378      ) 1 (         ) |  0 (39       ) 5 (         ) 6 (         ) |  0 (347      ) 0 (34       ) 2 (         ) |

最终结果

 3 (         ) 2 (         ) 9 (         ) |  1 (         ) 4 (         ) 7 (         ) |  6 (         ) 8 (         ) 5 (         ) | 5 (         ) 1 (         ) 4 (         ) |  8 (         ) 6 (         ) 2 (         ) |  3 (         ) 9 (         ) 7 (         ) | 6 (         ) 7 (         ) 8 (         ) |  3 (         ) 9 (         ) 5 (         ) |  2 (         ) 1 (         ) 4 (         ) | 1 (         ) 6 (         ) 7 (         ) |  5 (         ) 2 (         ) 8 (         ) |  4 (         ) 3 (         ) 9 (         ) | 4 (         ) 8 (         ) 3 (         ) |  7 (         ) 1 (         ) 9 (         ) |  5 (         ) 2 (         ) 6 (         ) | 2 (         ) 9 (         ) 5 (         ) |  6 (         ) 3 (         ) 4 (         ) |  8 (         ) 7 (         ) 1 (         ) | 7 (         ) 5 (         ) 2 (         ) |  4 (         ) 8 (         ) 1 (         ) |  9 (         ) 6 (         ) 3 (         ) | 9 (         ) 4 (         ) 6 (         ) |  2 (         ) 7 (         ) 3 (         ) |  1 (         ) 5 (         ) 8 (         ) | 8 (         ) 3 (         ) 1 (         ) |  9 (         ) 5 (         ) 6 (         ) |  7 (         ){4}(         ) 2 (         ) | ============数独解题完成,尝试次数为:45============

总结

在编写改算法的过程中,发现了数对方法考虑的场景漏了,补充了数对的场景。
相关链接:JAVA数独解题(四):数对法

代码详情

代码地址

JAVA数独解题(九):数链法(数串、垂直)相关推荐

  1. JAVA数独解题(四):数对法

    JAVA数独解题(四):数对法 说明 图片 算法代码 CalcEnum SuDuiCalc SudoUtil 输出结果 总结 代码详情 说明 数对:两个单元格,两个数字.两个数字在当前区域(行.列.宫 ...

  2. JAVA数独解题(一):框架搭建

    JAVA数独解题(一):框架搭建 前言 环境 创建工程 实体类 Box Sudo 监听器 SudoListener SudoPrintImpl 核心类 SudoHandler 算法组 Abstract ...

  3. JAVA数独解题(五):X-wing(矩阵法)

    JAVA数独解题(五):X-wing(矩阵法) 说明 图片 算法代码 CalcEnum XwingCalc YwingCalc SudoUtil 测试数据 输出结果 总结 代码详情 说明 参考文章:数 ...

  4. JAVA数独解题(七):XYZ-wing

    JAVA数独解题(七):XYZ-wing 说明 图片 算法代码 CalcEnum XYZwingCalc SudoUtil 测试数据 输出结果 总结 代码详情 说明 参考文章:数独高级技巧:XYZ-w ...

  5. 数独高阶技巧入门之四:简单异数链

    一.XY-Wing 图1 XY-Wing01 ​图1中,R2绿色三个双值格构成三链数,则在该行中X.Y.Z三个数字只能存在于绿色三格中.如果我们把三链数构成的直线掰弯,比如掰成像下图中的两种情况, Y ...

  6. Java多线程学习九:怎样确定线程数量及CPU 核心数和线程数的关系||如何定制自己的线程池

    调整线程池中的线程数量的最主要的目的是为了充分并合理地使用 CPU 和内存等资源,从而最大限度地提高程序的性能.在实际工作中,我们需要根据任务类型的不同选择对应的策略. CPU 密集型任务 首先,我们 ...

  7. 用java实现:有15个红球和15个绿球排成一圈,从第1个球开始数,当数到13个球时就取出此球,然后再从下一个球开始数,当再数到13时又取出。怎样循环取出所有的红球?

    java语言实现:有15个红球和15个绿球排成一圈,从第1个球开始数,当数到13个球时就取出此球,然后再从下一个球开始数,当再数到13时又取出.如此循环进行直到仅剩15个球为止,怎样排法才能使每次取出 ...

  8. Java 递归解决 quot;仅仅能两数相乘的计算器计算x^yquot; 问题

    Java 递归解决 "仅仅能两数相乘的计算器计算x^y" 问题 /*** 求一个数的乘方* 求x^y,y是一个正整数. 设计算器仅仅能计算两数相乘,不能一次计算n个数相乘. * 知 ...

  9. java统计行列和字数的函数_JAVA使用POI获取Excel的列数与行数

    前言 报表输出是Java应用开发中经常涉及的内容,而一般的报表往往缺乏通用性,不方便用户进行个性化编辑.Java程序由于其跨平台特性,不能直接操纵Excel.因此,本文探讨一下POI视线Java程序进 ...

最新文章

  1. 解决前后端base64编码传递时的中文乱码问题
  2. kaggle账号_机器学习竞赛入门--kaggle篇
  3. 基于 MVP 的 Android 组件化开发框架实践
  4. python基础教程: 自定义函数
  5. 2.关于QT中数据库操作,简单数据库连接操作,数据库的增删改查,QSqlTableModel和QTableView,事务操作,关于QItemDelegate 代理
  6. [vue] 父子组件间传值
  7. linux下运行程序后出现段错误的原因和解决案例
  8. idea ssm框架 mysql_IDEA 2017 整合SSM框架(使用Maven创建工程)
  9. Python简记--函数
  10. σ 代数与测度(measures)
  11. java正则匹配买火车票_matlab的正则表达式
  12. 人类(行为)动力学(1)——初步了解
  13. matlab imrotate中心,MATLAB imrotate函数的用法
  14. 梅西大学研究员创造出新3D打印系统 用螺杆作为进料机构挤出颗粒
  15. VS2015重装Team explorer报错
  16. 一部区块链创业者的“燃点” | 《8问》
  17. (Raw/High) P-Code Ghidra使用的中间表示语言
  18. FTTB+NAT+DHCP+pppoe+CBAC+*** client+Authentication AAA
  19. PHP爬虫,提取网站中的关键词,用一次正则匹配,然后再PHP数组的操作
  20. 高并发量网站解决方案

热门文章

  1. CH4INRULZ_v1.0.1内网渗透靶场
  2. 爆料一家互联网中厂的年终奖,真香。
  3. 常用数据类型和bytes数组互转
  4. 文本溢出变成省略号可多行
  5. 赏枫圣地:苏州的天平山
  6. 12星座情人圣诞礼物建议
  7. 6-8 连接字符串 (15 分)
  8. 注册美国公司怎么取名-跨境知道
  9. 计算机主机响是什么原因,电脑疑问_电脑主机响是什么原因-太平洋IT百科手机版...
  10. 3.HDFS之shell基本操作