[英]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: 您似乎尚不清楚两个问题:
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.
因此,想象一下一排复选框,每个复选框旁边都写有一个数字(数组索引)-这些复选框处于选中状态还是未选中状态,表明一个数字是否已使用。
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.