数独有效性检查算法 - 这段代码是如何工作的?
我正在阅读此处发布的一个问题: C# 中的数独算法
发布的解决方案之一是这个一段代码。
public static bool IsValid(int[] values) {
int flag = 0;
foreach (int value in values) {
if (value != 0) {
int bit = 1 << value;
if ((flag & bit) != 0) return false;
flag |= bit;
}
}
return true;
}
这个想法是它将检测值数组中的重复项;但我对自己的无知感到不知所措。有人可以向我解释一下吗?
编辑:谢谢大家。这么多精彩的答案,我不知道如何选择一个。现在它完全有道理了。
I was reading a question posted here: Sudoku algorithm in C#
And one of the solutions posted was this piece of code.
public static bool IsValid(int[] values) {
int flag = 0;
foreach (int value in values) {
if (value != 0) {
int bit = 1 << value;
if ((flag & bit) != 0) return false;
flag |= bit;
}
}
return true;
}
The idea is that it will detect duplicates in the array of values; but I'm overwhelmed by how much I don't know. Can someone explain this to me?
EDIT: Thanks everyone. So many great answers, I don't know how to select one. It now makes perfect sense.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
真是个好主意。
基本上,它使用
int
标志(最初设置为零)作为“位数组”;对于每个值,它检查标志中的相应位是否已设置,如果没有,则设置它。相反,如果该位位置已设置,则它知道相应的值已被看到,因此该数独块无效。
更详细:
Really a nice idea.
Basically, it uses an
int
flag (initially set to zero) as a "bit array"; for each value, it checks if the corresponding bit in the flag is set, and if it's not, it sets it.If, instead, that bit position is already set, it knows that the corresponding value has already been seen, so the piece of Sudoku is invalid.
More in detail:
让我们来解决它。
values = 1,2,3,2,5
迭代 1:
bit = 1 << 1
位 = 10
if(00 & 10 != 00)
false
标志 |= 位
flag = 10
迭代 2:
bit = 1 << 2
位 = 100
if(010 & 100 != 000)
false
标志 |= 位
flag = 110
迭代 3:
bit = 1 << 3
位 = 1000
if(0110 & 1000 != 0000)
false
标志 |= 位
flag = 1110
迭代 4:
bit = 1 << 2
bit = 100
if(1110 & 0100 != 0000)
TRUE
计算结果为 true,这意味着我们找到了一个 double ,并返回 falseLets work through it.
values = 1,2,3,2,5
Iteration 1:
bit = 1 << 1
bit = 10
if(00 & 10 != 00)
false
flag |= bit
flag = 10
Iteration 2:
bit = 1 << 2
bit = 100
if(010 & 100 != 000)
false
flag |= bit
flag = 110
Iteration 3:
bit = 1 << 3
bit = 1000
if(0110 & 1000 != 0000)
false
flag |= bit
flag = 1110
Iteration 4:
bit = 1 << 2
bit = 100
if(1110 & 0100 != 0000)
TRUE
This evaluates to true, meaning we found a double, and return false这个想法是设置数字的第 n 位,其中 n 是单元格值。由于数独值的范围为 1-9,因此所有位都在 0-512 的范围内。对于每个值,检查第 n 位是否已设置,如果是,则我们发现了重复项。如果没有,请设置支票号码的第 n 位(在本例中为
标志
),以累积已使用的号码。这是一种比数组更快的数据存储方式。The idea is to set the
nth
bit of a number, wheren
is the cell value. Since sudoku values range from 1-9, all the bits fit within a range of 0-512. With each value, check if thenth
bit is already set, and if so, we've found a duplicate. If not, set thenth
bit on our check number, in this caseflag
, to accumulate numbers that have already been used. It's a much faster way to store data than an array.有趣的。它通过在标志整数中设置该位来存储已经找到的数字。示例:
它还测试每个数字是否已在 flag-int 中设置该位。
Interesting. It stores the numbers it already found by setting that bit in the flag-integer. Example:
It also tests for each number if that bit is already set in the flag-int.
它检查数组中的值是否唯一。为此,它创建一个整数 - 标志 - 并根据值数组中的值设置标志中的位。它检查某个特定位是否已设置;如果是,则存在重复并且失败。否则,它会设置该位。
这是一个细分:
It checks to see if values in the array are unique. To do this, it creates an integer - flag - and it sets bits in the flag according to values in the array of values. It checks to see if a particular bit is already set; if it is, then there is a duplicate and it fails. Otherwise, it sets the bit.
Here's a breakdown: