提问人:yanasf 提问时间:10/3/2023 最后编辑:yanasf 更新时间:10/3/2023 访问量:91
为什么“i”变量会奇怪地递增?[关闭]
Why is the 'i' variable incrementing weirdly? [closed]
问:
给定一个具有有效解决方案的 9x9 数独网格。
我正在尝试编写一种方法来验证数独“框”(在本例中为 3x3 并且位于整个数独拼图内部)中(换句话说,检查重复项或超出范围的值)。我希望 3x3 网格内的每个索引都与其他值一起检查,看看这些值是否相等,如果相等,则 3x3 将无效。但是,我注意到(如果我没记错的话)“i”变量正在以一种奇怪的方式递增。首次调用 for 循环时,'i' 为 0,然后下一个增量 'i' 也是 0,最后一个增量 'i' 为 2。不知道为什么会这样。请让我知道我做错了什么
public boolean isValidBox(int row, int col) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++) {
if (grid[row + i][col + j] == grid[row + k][col + l] && i != k && j != l) {
return false;
}
}
}
}
}
return true;
}
我希望代码进行 81 次检查,换句话说,我期望这一行中的代码
if (grid[row + i][col + j] == grid[row + k][col + l] && i != k && j != l)
运行 81 次,但它没有这样做,我认为它运行了 243 次;81*3 更多次。
非常感谢。
答:
看起来您拥有的代码除了@Luatic指出的逻辑问题之外没有任何问题。您用于测量迭代次数的代码似乎可能是您所看到的问题的罪魁祸首。
如果您担心迭代次数和一般性能,可以尝试其他选项。例如,您可以切换到不重复比较的实现,例如仅执行 36 次迭代的实现。公平的警告,我没有执行任何基准测试。
boolean isValidBox(int row, int col) {
for (int i = 0; i < 8; i++) {
int iRow = (i / 3) + row;
int iCol = (i % 3) + col;
for (int j = i + 1; j < 9; j++) {
int jRow = (j / 3) + row;
int jCol = (j % 3) + col;
if (grid[iRow][iCol] == grid[jRow][jCol]) {
return false;
}
}
}
return true;
}
更好的解决方案是在更新单元格时仅检查重复项,因此您只需执行一次传递即可搜索单元格的新值。
"...我正在尝试编写一种方法来验证数独“框”(在本例中为 3x3 并且位于整个数独拼图内部)中(换句话说,检查重复项或超出范围的值)。..."
作为参考,以下问题对此问题有一些很好的答案。
StackOverflow – Java 数独方块 3x3 检查有效性
"...我注意到......“i”变量以一种奇怪的方式递增。首次调用 for 循环时,'i' 为 0,然后下一个增量 'i' 也是 0,最后一个增量 'i' 为 2。不知道为什么会这样。请让我知道我做错了什么......”
按如下方式查看数独网格。
0 0 0 1 1 1 2 2 2
0 0 0 1 1 1 2 2 2
0 0 0 1 1 1 2 2 2
3 3 3 4 4 4 5 5 5
3 3 3 4 4 4 5 5 5
3 3 3 4 4 4 5 5 5
6 6 6 7 7 7 8 8 8
6 6 6 7 7 7 8 8 8
6 6 6 7 7 7 8 8 8
将行和列转换为封闭的“框”的左上角索引。
其中,您可以迭代 3 个步骤,3 次,以评估价值。
boolean valid(int r, int c, int value) {
Function<Integer, Integer> f
= x -> switch (x) {
case 0, 1, 2 -> 0;
case 3, 4, 5 -> (x / 3) + 2;
case 6, 7, 8 -> (x / 3) + 4;
default -> -1;
};
r = f.apply(r);
c = f.apply(c);
for(int i = r, j; i < r + 3; i++)
for(j = c; j < c + 3; j++)
if(grid[i][j] == value) return false;
return true;
}
下面是一个示例,使用维基百科中的网格。
double[][] grid = {
{ 5, 3, 0, 0, 7, 0, 0, 0, 0 },
{ 6, 0, 0, 1, 9, 5, 0, 0, 0 },
{ 0, 9, 8, 0, 0, 0, 0, 6, 0 },
{ 8, 0, 0, 0, 6, 0, 0, 0, 3 },
{ 4, 0, 0, 8, 0, 3, 0, 0, 1 },
{ 7, 0, 0, 0, 2, 0, 0, 0, 6 },
{ 0, 6, 0, 0, 0, 0, 2, 8, 0 },
{ 0, 0, 0, 4, 1, 9, 0, 0, 5 },
{ 0, 0, 0, 0, 8, 0, 0, 7, 9 }
};
输出
valid(0, 2, 4) = true
valid(0, 2, 5) = false
评论
grid[row + i][col + j] == grid[row + k][col + l] && i != k && j != l
i != k
j != l
i != k
i != l
grid[row + i][col + j] == grid[row + k][col + l] && (i != k || j != l)