为什么“i”变量奇怪地递增?

问题描述 投票:0回答:2

给定 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 次以上。

非常感谢。

java sudoku nested-for-loop
2个回答
0
投票

看起来你的代码除了@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;
}

更好的解决方案是在更新单元格时仅检查重复项,因此您只需执行一次即可搜索单元格的新值。


0
投票

“...我正在尝试编写一种方法,用于在数独“盒子”(在本例中为 3x3 且位于整个数独谜题的内部)中进行验证(换句话说,检查重复项或超出范围的值) )....”

作为参考,以下问题对此问题有一些很好的答案。
StackOverflow – Java Sudoku Squares 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
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;
        };
    c = f.apply(c);
    r = f.apply(r);
    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;
}

这是一个示例,使用来自 Wikipedia 的网格。

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
© www.soinside.com 2019 - 2024. All rights reserved.