如何循环数独板?
例如,假设我们有一个像这样的数独板:
0 0 6 5 8 9 7 4 3
0 5 0 0 0 0 0 6 0
7 0 9 0 6 0 1 0 0
0 3 0 0 0 2 0 8 7
0 0 1 0 0 0 4 0 0
8 9 0 6 0 0 0 5 0
0 0 2 0 5 0 3 0 6
0 7 0 0 0 0 0 9 0
3 1 8 4 9 6 5 0 0
我想将其存储到一个数组中,使得该数组的前 9 个元素是第一个子块,即值 {0 0 6 0 5 0 7 0 9}
,然后是 {5 8 9 0 0 0 0 6 0}
。
我尝试寻找解决方案,但总是出现数组索引越界错误,而且它太暴力了。类似的事情:
while(st.hasMoreTokens()) {
if(ctr == 27) {
c.addSubBlock(sb1);
c.addSubBlock(sb2);
c.addSubBlock(sb3);
sb1 = new SubBlock();
sb2 = new SubBlock();
sb3 = new SubBlock();
ctr = 0;
}
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
ctr+=9;
}
请给我一些提示。代码片段也会有很大的帮助。
编辑:这个线程 以某种方式帮助我弄清楚了。是的,这是数独的一部分,我试图将棋盘编码到数组中。
我所做的就是首先将输入字符串转换为二维数组 (9x9) 并使用 int block = (row/3)*3 + (col/3); 来准确计算每个子块元素所属。
For example, say we have a Sudoku board like this:
0 0 6 5 8 9 7 4 3
0 5 0 0 0 0 0 6 0
7 0 9 0 6 0 1 0 0
0 3 0 0 0 2 0 8 7
0 0 1 0 0 0 4 0 0
8 9 0 6 0 0 0 5 0
0 0 2 0 5 0 3 0 6
0 7 0 0 0 0 0 9 0
3 1 8 4 9 6 5 0 0
I want to store it into one array such that the first 9 elements of the array are the first sub block, i.e. the values {0 0 6 0 5 0 7 0 9}
and followed by {5 8 9 0 0 0 0 6 0}
.
I've tried finding a solution but I always get an array index out of bounds error and it is too brute force. Something similar to this:
while(st.hasMoreTokens()) {
if(ctr == 27) {
c.addSubBlock(sb1);
c.addSubBlock(sb2);
c.addSubBlock(sb3);
sb1 = new SubBlock();
sb2 = new SubBlock();
sb3 = new SubBlock();
ctr = 0;
}
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb1.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb2.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
sb3.addElement(Integer.parseInt(st.nextToken()));
ctr+=9;
}
Please give me some tips. Code snippets would also be a great help.
EDIT: This thread somehow helped me figured it out. And yes, this is part of the Sudoku where I'm trying to encode the board into an array.
What I did was to transform first the input String into a 2d array (9x9) and use int block = (row/3)*3 + (col/3);
to compute exactly which sub block each element belongs.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
中像这样:
board[0][0] 将是左上角的子块,board[2][2] 是右下角的子块。
Something like this:
board[0][0] will be the top-left SubBlock, board[2][2] the bottom-right one.
将所有内容存储在二维数组中。例如
Store everything in a two dimension array. E.g.
假设您正在从左到右、从上到下读取输入,请尝试一组 4 个嵌套循环,如下所示:
Assuming that you are reading input left to right, top to bottom, try a set of 4 nested loops like this:
如果我们知道您为什么要尝试循环遍历该板,那就太好了。
如果您想检查是否可以输入数字,我建议您对每个 3x3 方块使用地图。
然后检查该项目是否已经在地图中。对于行和列,您可以循环遍历二维数组并检查每个元素,或者再次对每列使用一个映射,对每行使用一个映射。
It would be great if we knew why you are trying to loop through the board.
If you want to check if you can enter a number, I recommend you use maps for each of the 3x3 squares.
Then check if the item is in the map already or not. For the rows and columns, you can either loop over the 2D array and check each element, or -again- use a map for each column and a map for each row.
我不完全确定您是否想要单维数组的答案,或者您是否愿意将其设为二维数组(正如您提到的用大括号设置的每九个元素),但如果二维是好的...
此代码审查帖子中的OP使用了一种“奇特”的方式筛选通过通过在其中一个方括号内使用数学
(i % 3) + rowStart
和在另一个方括号内使用(i / 3) + colStart
来创建子网格。一位评论者指出这种模数方法有点晦涩,我很容易同意,但考虑到它的简洁性以及它的工作原理,我认为这是一个可靠的解决方案。因此,与 for 循环的迭代相结合,我们可以筛选每个“子网格”单元格以及 row + col 的每个元素。如果我们在一个匹配的单元格中找到一个数字,则它是重复的,我们将函数作为“假”或 0 退出。
编辑:
现在我想到了,您可以使用对于一维数组也有同样的技巧,使用
i % 9
而不是 3。然后,您可以通过执行i / 9
来确定我们所在的“行”相信这一点,因为我们处理 int 类型时,我们将截断不必要的小数。这确实验证了这个技巧有点倾向于 N-1 索引数据,因为有人会认为“转到第 81 个元素”意味着转到第 9 行的第 9 列,但使用 81 % 9 将产生 0,并且81 / 9 将得到 9,因此我们将转到第 9 行的第 0 个位置。
I'm not entirely sure if you want an answer for a single-dimension array or if you're willing to make it a two-dimensional array (as you mention each nine element set with curly braces), but if two-dimensional is OK...
The OP in this Code Review posting used a 'fancy' way of sifting through the subgrids by using the math
(i % 3) + rowStart
inside one of the square brackets and(i / 3) + colStart
inside the other. One commenter noted this modulo method to be a bit obscure, and I'm prone to agree, but for how clean it is and the fact that it works, I think it's a solid solution. So, paired with the iteration of the for loop, we can sift through each 'subgrid' cell, as well as each element of row + col.If we find a number in one of the cells that matches, it's a duplicate, and we exit the function as 'false', or, 0.
EDIT:
Now that I think of it, you could use this same trick for a single-dimension array by using
i % 9
instead of 3. You could then determine which 'row' we're on by doingi / 9
and trusting that, since we're dealing with typeint
s, we'll truncate the unnecessary decimals.This does verify that this trick is a bit prone towards N-1 indexed data, as someone would assume 'go to the 81st element' would mean go to the 9th column of the 9th row, but using 81 % 9 would yield 0, and 81 / 9 would yield 9, so we'd go to the 0th place at row 9.