java中数独填数问题

img


随机生成一个数独,然后在数独中进行填数,求一个好用的代码来解决问题


{

    public static void main(String[] args) {
        int[][] sudoku = {
                {5,4,6,8,7,9,1,3,2},
                {2,1,3,5,4,6,0,9,8},
                {8,7,9,0,1,3,4,6,5},
                {3,2,4,0,5,7,0,1,9},
                {9,8,1,3,2,4,0,7,0},
                {6,5,7,9,8,1,2,4,3},
                {7,6,8,1,9,2,3,5,4},
                {4,3,5,7,6,8,9,2,0},
                {1,9,2,0,3,5,0,8,7}

        };

        System.out.println("原始数独题目:");
        printSudoku(sudoku);

        System.out.println("求解结果:");
        if (solveSudoku(sudoku)) {
            printSudoku(sudoku);
        } else {
            System.out.println("-1");
        }
    }

    // 求解数独
    public static boolean solveSudoku(int[][] sudoku) {
        int n = sudoku.length;

        // 找到一个空缺的格点
        int[] emptyCell = findEmptyCell(sudoku, n);
        if (emptyCell == null) {
            // 数独已被填满,求解完成
            return true;
        }

        int row = emptyCell[0];
        int col = emptyCell[1];

        // 尝试填入数字
        for (int num = 1; num <= n; num++) {
            if (isValidMove(sudoku, row, col, num)) {
                sudoku[row][col] = num;
                if (solveSudoku(sudoku)) {
                    return true; // 找到解
                }
                sudoku[row][col] = 0; // 回溯,重置格点为0
            }
        }

        return false; // 没有找到解
    }

    // 找到一个空缺的格点
    public static int[] findEmptyCell(int[][] sudoku, int n) {
        for (int row = 0; row < n; row++) {
            for (int col = 0; col < n; col++) {
                if (sudoku[row][col] == 0) {
                    return new int[]{row, col};
                }
            }
        }
        return null;
    }

    // 判断在指定的位置是否可以填入数字
    public static boolean isValidMove(int[][] sudoku, int row, int col, int num) {
        int n = sudoku.length;

        // 检查行和列
        for (int i = 0; i < n; i++) {
            if (sudoku[row][i] == num || sudoku[i][col] == num) {
                return false;
            }
        }

        // 检查九宫格
        int sqrt = (int) Math.sqrt(n);
        int startRow = row - row % sqrt;
        int startCol = col - col % sqrt;
        for (int i = startRow; i < startRow + sqrt; i++) {
            for (int j = startCol; j < startCol + sqrt; j++) {
                if (sudoku[i][j] == num) {
                    return false;
                }
            }
        }

        return true;
    }

    // 打印数独
    public static void printSudoku(int[][] sudoku) {
        int n = sudoku.length;
        for (int row = 0; row < n; row++) {
            for (int col = 0; col < n; col++) {
                System.out.print(sudoku[row][col] + " ");
            }
            System.out.println();
        }
    }
}

https://blog.csdn.net/m0_71905144/article/details/128207140


import java.util.Arrays;
import java.util.Random;

public class SudokuSolver {
    private static final int SIZE = 9;
    private static final int EMPTY_CELL = 0;

    public static void main(String[] args) {
        int[][] grid = new int[SIZE][SIZE];
        generateSudoku(grid);
        printSudoku(grid);
        solveSudoku(grid);
        System.out.println("\nSolved Sudoku:");
        printSudoku(grid);
    }

    private static void generateSudoku(int[][] grid) {
        Random rand = new Random();
        solveSudoku(grid);
        int numToRemove = rand.nextInt(26) + 25; // 25-50个数字将被移除
        for (int i = 0; i < numToRemove; i++) {
            int row = rand.nextInt(SIZE);
            int col = rand.nextInt(SIZE);
            while (grid[row][col] == EMPTY_CELL) {
                row = rand.nextInt(SIZE);
                col = rand.nextInt(SIZE);
            }
            grid[row][col] = EMPTY_CELL;
        }
    }

    private static boolean solveSudoku(int[][] grid) {
        int row = -1;
        int col = -1;
        boolean isEmpty = true;

        for (int i = 0; i < SIZE; i++) {
            for (int j = 0; j < SIZE; j++) {
                if (grid[i][j] == EMPTY_CELL) {
                    row = i;
                    col = j;
                    isEmpty = false;
                    break;
                }
            }
            if (!isEmpty) {
                break;
            }
        }

        if (isEmpty) {
            return true;
        }

        for (int num = 1; num <= SIZE; num++) {
            if (isSafe(grid, row, col, num)) {
                grid[row][col] = num;
                if (solveSudoku(grid)) {
                    return true;
                } else {
                    grid[row][col] = EMPTY_CELL;
                }
            }
        }
        return false;
    }

    private static boolean isSafe(int[][] grid, int row, int col, int num) {
        // 检查行和列
        for (int i = 0; i < SIZE; i++) {
            if (grid[row][i] == num || grid[i][col] == num) {
                return false;
            }
        }

        // 检查小九宫格
        int startRow = row - row % 3;
        int startCol = col - col % 3;
        for (int i = 0; i < 3; i++) {
            for (int j = 0; j < 3; j++) {
                if (grid[i + startRow][j + startCol] == num) {
                    return false;
                }
            }
        }
        return true;
    }

    private static void printSudoku(int[][] grid) {
        for (int[] row : grid) {
            System.out.println(Arrays.toString(row));
        }
    }
}

上述代码中,generateSudoku方法用于随机生成一个数独谜题,solveSudoku方法用于解决数独谜题。isSafe方法用于检查当前位置是否安全填入一个数。printSudoku方法用于打印数独格局。最后,你需要执行main方法来生成一个随机数独并进行填数。输出将包含生成的数独和解决后的数独。