简体   繁体   English

Java Sudoku蛮力求解器,它如何工作?

[英]Java Sudoku brute force solver, how does it work?

So you find the code below here. 因此,您可以在下面找到以下代码。 Most of the code I understand, but there is one bit I don't. 我了解大多数代码,但有一点我不了解。 The place where we create the boolean array called digits and the bit after that 3 * (x / 3) . 我们在其中创建称为digits的布尔数组的地方,其后是3 * (x / 3)

I think it's used to check if each square in the sudoku has 9 unique numbers as well, but I'm not sure on how I can explain this to let's say someone next to me. 我认为它用来检查数独中的每个方块是否也有9个唯一数字,但是我不确定如何解释这一点,比如说我旁边有人。

Why do I need the array of boolean here? 为什么在这里需要布尔数组? Can someone explain to me what it is doing and why? 有人可以向我解释它在做什么,为什么?

Kind regards! 亲切的问候!

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;
}

I have added some explanation as comments inline: 我添加了一些解释作为内联注释:

//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;
    }
}

There seem to be two issues you are unclear on: 您似乎尚不清楚两个问题:

  1. The boolean array - this array is used to track which digits have been used already on a specific row or column. 布尔数组-此数组用于跟踪特定行或列上已经使用了哪些数字。 So imagine a row of tick boxes each with a digit written next to it (the array index) - these boxes are checked or unchecked to show a digit has been used or not. 因此,想象一下一排复选框,每个复选框旁边都写有一个数字(数组索引)-这些复选框处于选中状态还是未选中状态,表明一个数字是否已使用。

  2. The expressions 3* (x/3) and 3 * (y/3) - what you need to remember here is that this is integer division (that means the result of the division is always rounded down to an integer. For example if x=1 then 3 (x/3) is 3 (1/3) is 3 * (0) =0 (whereas if this was float division the result would be 3*(0.3333)=1. So these maths expressions essentially change you number to the next lowest multiple of three - that is 1 -> 0, 2 -> 0, 3 -> 3, 4 -> 3 etc. 表达式3 *(x / 3)和3 *(y / 3)-这里需要记住的是这是整数除法(这意味着除法的结果总是四舍五入为整数。例如,如果x = 1,那么3 (x / 3)是3 (1/3)是3 *(0)= 0(而如果这是float除法,则结果将是3 *(0.3333)= 1。因此,这些数学表达式实质上会改变您数字到三的下一个最低倍数-即1-> 0,2-> 0,3-> 3,4-> 3等

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM