Java 数独暴力解算器,它是如何工作的?

Java Sudoku brute force solver, how does it work?

因此,您可以在此处找到下面的代码。我理解大部分代码,但有一点我不理解。我们创建名为 digits 的布尔数组的位置以及之后的位 3 * (x / 3)

我认为它用于检查数独中的每个方块是否也有 9 个唯一数字,但我不确定如何向我旁边的人解释这一点。

为什么这里需要布尔数组?有人可以向我解释一下它在做什么以及为什么吗?

亲切的问候!

public int[][] solvePuzzle(int[][] matrix) {
    int x, y = 0;

    boolean found = false;

    // First we check if the matrix contains any zeros.
    // If it does we break out of the for loop and continue to solving the puzzle.
    for (x = 0; x < 9; x++) {
        for (y = 0; y < 9; y++) {
            if (matrix[x][y] == 0) {
                found = true;
                break;
            }
        }

        if (found) {
            break;
        }
    }

    // If the puzzle doesn't contain any zeros we return the matrix
    // We now know that this is the solved version of the puzzle
    if (!found) {
        return matrix;
    }

    boolean digits[] = new boolean[11];

    for (int i = 0; i < 9; i++) {
        digits[matrix[x][i]] = true;
        digits[matrix[i][y]] = true;
    }

    int boxX = 3 * (x / 3), boxY = 3 * (y / 3);
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            digits[matrix[boxX + i][boxY + j]] = true;
        }
    }

    // We loop over all the numbers we have to check if the next number fits in the puzzle
    // We update the matrix and check recursively by calling the same function again to check if the puzzle is correct
    // If it's not correct we reset the matrix field to 0 and continue with the next number in the for loop
    for (int i = 1; i <= 9; i++) {
        if (!digits[i]) {
            matrix[x][y] = i;

            if (solvePuzzle(matrix) != null) {
                return matrix;
            }

            matrix[x][y] = 0;
        }
    }

    // The puzzle can't be solved so we return null
    return null;
}

我在评论中添加了一些解释:

//we need to know what digits are we still allowed to use
//(not used in this row, not used in this column, not used in
//the same 3x3 "sub-box")
boolean digits[] = new boolean[11];

//so we run through the rows/coumns around the place (x,y)
//we want to fill in this iteration
for (int i = 0; i < 9; i++) {
    //take a used number from the row of x (matrix[x][i]) and mark it
    // as used
    digits[matrix[x][i]] = true;
    //take a used number from the column of y (matrix[i][y]) and mark it
    // as used
    digits[matrix[i][y]] = true;
}

//find the top-left corner of the sub-box for the position (x,y) we
//want to fill in
//example: x is 8 -> 3 * 8/3 -> 6, so we start from 6
int boxX = 3 * (x / 3), boxY = 3 * (y / 3);

//iterate through the sub-box horizontally and vertically
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
    //take a used number from the sub-box and mark it
    // as used
        digits[matrix[boxX + i][boxY + j]] = true;
    }
}

您似乎有两个问题不清楚:

  1. 布尔数组 - 该数组用于跟踪特定行或列上已经使用了哪些数字。因此,想象一下一行勾选框,每个勾选框旁边都有一个数字(数组索引)——这些框被选中或未选中以显示是否使用了一个数字。

  2. 表达式 3* (x/3) 和 3 * (y/3) - 你需要记住的是这是整数除法(这意味着结果除法总是向下舍入为整数。例如,如果 x=1,则 3 (x/3) 是 3 (1/3) 是 3 * (0) =0 (而如果这是浮点除法,则结果将是 3*(0.3333)=1。因此,这些数学表达式实质上会将您的数字更改为下一个最小的三倍数 - 即 1 -> 0, 2 -> 0, 3 -> 3、4 -> 3 等等