【小DEMO】回溯法破解数独

import java.util.*;

public class Sudoku {
    // 方案数量
    public static int caseCount;
    // sudoku 二位数组
    public static int[][] chessboard=new int[9][9];
    // 初始化二位数组
    public static void init(){
        chessboard = new int[][]{
                {7,0,0,0,0,4,0,2,0},
                {0,9,0,0,0,0,3,0,0},
                {0,0,0,0,0,6,0,0,8},

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

                {0,0,9,5,2,0,0,0,0},
                {0,0,0,0,0,0,8,6,7},
                {1,0,0,3,0,0,0,0,0}
        };
        // 静态Int型数据默认是0,这里初始化方便逻辑书写
        caseCount = 0;
    }
    // 查找可用集合
    public static Set<Integer> canUse(int row, int col){
        Set<Integer> set = new HashSet<>(Arrays.asList(1,2,3,4,5,6,7,8,9));
        // 排除行上数据
        for (int index = 0;index <=8; index++){
            set.remove(chessboard[row][index]);
        }
        // 排除列上数据
        for (int index = 0;index <=8; index++){
            set.remove(chessboard[index][col]);
        }
        // 排除方格内的数据
        int xxx = row/3;
        int yyy = col/3;
        for (int y = yyy*3; y<(yyy+1)*3; y++){
            for (int x = xxx*3; x<(xxx+1)*3; x++){
                set.remove(chessboard[x][y]);
            }
        }
        return set;
    }

    // 查找下一个
    public static int[] next(int row, int col){
        // 某行还没走到尽头
        if (col<8){
            return new int[]{row,++col};
        }
        // 如果某行走到尽头
        if (col == 8 && row<8){
            return new int[]{++row,0};
        }
        // 如果行和列都走到尽头,返回null
        return null;
    }

    // 打印结果
    public static void printResult(){
        for (int row = 0; row<=8; row++){
            for (int col = 0; col<=8; col++){
                System.out.print(chessboard[row][col] + " ");
                if ((col+1)%3==0){
                    System.out.print("  ");
                }
            }
            System.out.println();
            if ((row+1)%3==0){
                System.out.println();
            }
        }
    }

    // 添加数字
    public static void fillNumber(int row, int col){
        // 当前值为空位的时候
        if (chessboard[row][col] == 0){
            // 先查找所有可能
            Set<Integer> canUseSet = canUse(row,col);
            List<Integer> list = new ArrayList<>(canUseSet);
            for (Integer integer:list){
                    chessboard[row][col] = integer;
                    // 查找下一个
                    int[] nextPosition = next(row, col);
                    if (Objects.isNull(nextPosition) || nextPosition.length == 0){
                        //可以输出一个结果
                        System.out.println("结果"+(++caseCount)+":");
                        printResult();
                    }else {
                        //查找下一个
                        int newRow = nextPosition[0];
                        int newCol = nextPosition[1];
                        fillNumber(newRow,newCol);
                    }
                    chessboard[row][col] = 0;
            }
        }else {
            int[] nextPosition = next(row, col);
            if (Objects.isNull(nextPosition) || nextPosition.length == 0){
                //可以输出一个结果
                System.out.println("结果"+(++caseCount)+":");
                printResult();
            }else {
                //查找下一个
                int newRow = nextPosition[0];
                int newCol = nextPosition[1];
                fillNumber(newRow,newCol);
            }
        }
    }

    public static void main(String[] args) {
        // 初始化
        init();
        System.out.println("原始数据:");
        printResult();
        System.out.println("结果集:");
        fillNumber(0,0);
    }
}
发布了63 篇原创文章 · 获赞 18 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 技术工厂 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览