如何在Java中验证Sudoku网格的有效性?

时间:2016-01-12 00:11:26

标签: java for-loop sudoku

我试图创建一个数独程序来检查数独网格是否有效。我想出了如何检查每一行是否有效,以及每列是否有效。但是,我在编写代码时无法检查网格中的9个小方框。 以下是我尝试用来检查每个小方框的方法。对于小方框中的每个空格,只能显示一个数字,否则该方法将返回false。

    public static boolean isValidSquare(int[][] grid, int i, int j) {
    int[][] square = new int[3][3];
    int row = 0; int column = 0;
    for (int x = i; x < i + 3; x++) {
        for (int y = j; y < j + 3; y++) {
            square[row][column] = grid[x][j];
            column++;
        }
        row++;
    }
    return true;
}

但是,当我运行它时,该方法始终返回true。我试过将for循环中的条件分别改为i + 2和j + 2,它仍然给我同样的问题。

或者它是否与这段抛出方法的代码有关?

    for (int i = 0; i < grid.length; i += 3) {
        for (int j = 0; j < grid[i].length; j += 3) {
            if (isValidSquare(grid, i, j) == false)
                return false;
        }
    }

更新:只是测试了哪些方法有效,程序甚至没有到达ValidSquare部分,Column部分是返回false的方法:

    public static boolean isValidColumn(int[][] grid, int i) {
    for (int j = 0; j < grid[0].length - 1; j++) {
        for (int k = j; k < grid.length; k++) {
            if ((grid[j][i] < 1 || grid[j][i] > 9) || grid[j][i] == grid[k][i])
                return false;
        }
    }
    return true;

我无法弄清楚是什么导致它不断宣布错误,我打印并检查了每一栏,看起来很好。

编辑2:好的,第一列只是因为我将k =设置为j而不是j + 1. subsquare方法的另一个问题仍然困扰着我,因为它会在&#39; 3处抛出OutOfBoundsException #39;

4 个答案:

答案 0 :(得分:1)

isValidSquare的最大问题是您始终return true。即使粗略地查看代码也不会产生甚至return false的行。

答案 1 :(得分:1)

你的方法

public static boolean isValidSquare(int[][] grid, int i, int j) {
    int[][] square = new int[3][3];
    int row = 0; int column = 0;
    for (int x = i; x < i + 3; x++) {
        for (int y = j; y < j + 3; y++) {
            square[row][column] = grid[x][j];
            column++;
        }
        row++;
    }
    return true;
}

始终返回true。只有一个return声明。

  

或者它是否与这段抛出方法的代码有关?

我不确定这对&#34;扔掉&#34;一个方法,但条件

isValidSquare(grid, i, j) == false
基于之前的假设,

永远不会成真。

我必须在这里质疑一般设计:为什么isValidSquare仍然是static函数?

为什么不为数独网格创建一个类,并提供设置数字,检查有效性等的方法?

您的static方法适用于任何int[][],其中包括那些甚至无效的数独网格。如果您有一个封装良好的SudokuGrid类,则可以安全地假设正确调整大小和初始化的内部private数据结构。 isValidSquare很高兴地接受了int的2x2网格,这是不可取的。

答案 2 :(得分:1)

您的代码中有拼写错误:

public static boolean isValidSquare(int[][] grid, int i, int j) {
 int[][] square = new int[3][3];
 int row = 0; int column = 0;
 for (int x = i; x < i + 3; x++) {
     for (int y = j; y < j + 3; y++) {
         square[row][column] = grid[x][j]; // j should be y
         column++;
     }
     row++;
 }
return true;
}

我猜这就是为什么它没有像你期望的那样表现。

另外,正如其他人所说,你的方法永远不会返回false并且它将无法正常工作,但它是相当明显的。

我建议通过将其内容写入集合来验证小方框的有效性,并在方法yourSet.add(number)返回false时返回false

答案 3 :(得分:0)

认为我得到了这个问题并且很乐意接受某些事情,这可能对你有所帮助......希望如此。

我不能专门针对JavaScript发言,但很久以前我在c中写了类似的程序。如果将值存储在9x9数组中,则可以通过一些简单的乘法来完成此操作。

如果你认为 - 你有9个小块或正方形是3x3所以3是一个黄金数字。

我们可以将这些排列成行和列,如下所示:

    # # # | # # # | # # #
    # # # | # # # | # # #
    # # # | # # # | # # #
    ---------------------
    # # # | # # # | # # #
    # # # | # # # | # # #
    # # # | # # # | # # #
    ---------------------
    # # # | # # # | # # #
    # # # | # # # | # # #
    # # # | # # # | # # #

这将它排列到你需要检查的那些块中,我们需要能够引用一个块,所以让我们给它们坐标 - 我们可以说我们的整个数独网格是一个3x3的块网格。坐标 - 0,0引用左上方的块,1,0是顶部中间的块,0,2是右上方的块等等......直到我们到达2,2引用右下方的块

现在我们可以引用一个块,我们可以编写一个基本函数来循环遍历给定块中的每个值,例如......

/**
 * We can reference any block by setting row and col, for example:
 *
 *    check_block(grid, 0, 0);
 *
 * To reference the upper-left block, or:
 *
 *    check_block(grid, 2, 2);
 *
 * To reference the bottom-right block.
 */
function check_block(grid, row, col) {
    /**
     * We'll use x to index the elements of the horizontal row of a given
     * block, and y to index the elements of the vertical column.
     */
    var x, y;

    /**
     * We know each block is a 3x3 square - we can cycle through these
     * using a couple of nested loops...
     */
    for (y = 0; y < 3; y++) {
       for (x = 0; x < 3; x++) {
          /**
           * To index the digit within the block we simply multiply our
           * row with 3 and add it to y and our col with 3 and add that
           * to x...
           */
          grid[(y + (row * 3))][(x + (col * 3))] ...
       }
    }
}

如果你坐下来用笔和纸来解决这个问题 - 假设我们想要检查方框2,2中的值。

由于每个块都是3x3数组,3是我们的黄金数,所以将行(2)和col(2)乘以3,所以基本上我们引用的是单元格6,6。

因此,通过循环3x3平方并添加x和y值,我们正在处理该单个块:

y = 0, x = 0      y = 0, x = 1      y = 0, x = 2
6,6               6,7               6,8

y = 1, x = 0      y = 1, x = 1      y = 1, x = 2
7,6               7,7               7,8

等等......抱歉过度啰嗦,并不确定它是否会有所帮助。虽然这是一个很小的代码,并且可以用于各种各样的事情,数独网格就是其中之一。它可能不完全符合你的代码,但它背后的理论是坚实的,非常实用。

希望你从中获得有用的东西,并祝你的编码更好。