我试图创建一个数独程序来检查数独网格是否有效。我想出了如何检查每一行是否有效,以及每列是否有效。但是,我在编写代码时无法检查网格中的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;
答案 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
等等......抱歉过度啰嗦,并不确定它是否会有所帮助。虽然这是一个很小的代码,并且可以用于各种各样的事情,数独网格就是其中之一。它可能不完全符合你的代码,但它背后的理论是坚实的,非常实用。
希望你从中获得有用的东西,并祝你的编码更好。