栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

JAVA 递归 + 回溯 实现数独

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

JAVA 递归 + 回溯 实现数独

递归:

递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。递归的能力在于用有限的语句来定义对象的无限集合。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。

回溯:

回溯法主要采用试错的思想,它在试错的过程中,如果不能得到一个正确的答案,它可能回退至上一步,甚至重头开始计算。

建议参考:八皇后问题

上代码:

1.给定一个存在唯一解的有效数独

    public static int[][] boards = {{5, 3, 0, 0, 7, 0, 0, 0, 0}, {6, 0, 0, 1, 9, 5, 0, 0, 0}, {0, 9, 8, 0, 0, 0, 0, 6, 0}, {8, 0, 0, 0, 6, 0, 0, 0, 3}, {4, 0, 0, 8, 0, 3, 0, 0, 1}, {7, 0, 0, 0, 2, 0, 0, 0, 6}, {0, 6, 0, 0, 0, 0, 2, 8, 0}, {0, 0, 0, 4, 1, 9, 0, 0, 5}, {0, 0, 0, 0, 8, 0, 0, 7, 9}};

2.实现递归

public static void main(String[] args) {
    //解法:递归回溯
    //数独原型
    System.out.println("求:");
    for (int[] board : boards) {
        System.out.println(Arrays.toString(board));
    }
    //实现递归
    //从第一行第一列执行
    calculation(0, 0);
    System.out.println("解:");
    for (int[] board : boards) {
        System.out.println(Arrays.toString(board));
    }
}
    
    public static boolean calculation(int x, int y) {
        //所有行执行完毕退出
        if (x  == totalRow) {
            return true;
        }

        //校验x-y轴对应数据是否为待填写
        if (0 == boards[x][y]) {
            for (int i = 1; i <= totalNum; i++) {
                //校验当前值是否可填入当前x-y轴
                if (check(x, y, i)) {
                    //设置x-y轴对应值
                    boards[x][y] = i;
                    //执行下一次递归
                    boolean isOk = nextCalculation(x, y);
                    if (isOk) {
                        //True:成功
                        return true;
                    } else {
                        //False:失败
                        //下一单元格执行失败,将历史填写的值置0。
                        boards[x][y] = 0;
                    }
                }
            }
        } else {
            return nextCalculation(x, y);
        }
        return false;
    }

 3.实现下一次递归校验

    
    public static boolean nextCalculation(int x, int y) {
        return y + 1 == totalColumn ? calculation(x + 1, 0) : calculation(x, y + 1);
    }

4.校验数值是否能填入对应单元格 

    
    public static boolean check(int x, int y, int num) {
        //校验X轴
        for (int i = 0; i < totalNum; i++) {
            if (boards[x][i] == num) {
                return false;
            }
        }

        //校验Y轴
        for (int i = 0; i < totalNum; i++) {
            if (boards[i][y] == num) {
                return false;
            }
        }

        //校验当前矩阵
        for (int i = 3 * (x / 3); i < 3 * (x / 3) + 3; i++) {
            for (int j = 3 * (y / 3); j < 3 * (y / 3) + 3; j++) {
                if(boards[i][j] == num){
                    return false;
                }
            }
        }

        return true;
    }

5.结果

 创作不易,不喜勿喷,望指点!

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/884280.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号