我正在使用以下技巧来遍历 int 的位集:
while (b != 0)
{
c = b & (0 - b);
//Do something...
b = b ^ c;
}
以数字 4128(二进制 0001000000100000)为例,因为 c 的值是 32 和 4096,所以可以正常工作。
但是,我想要的不是实际值,而是这些值的位置,它们是 5 和 12。
是否有额外的代码行可以插入到返回位置的循环中?
我正在使用以下技巧来遍历 int 的位集:
while (b != 0)
{
c = b & (0 - b);
//Do something...
b = b ^ c;
}
以数字 4128(二进制 0001000000100000)为例,因为 c 的值是 32 和 4096,所以可以正常工作。
但是,我想要的不是实际值,而是这些值的位置,它们是 5 和 12。
是否有额外的代码行可以插入到返回位置的循环中?
您可以使用Integer.numberOfTrailingZeros
来获取位索引,如下所示:
while (b != 0)
{
c = b & (0 - b);
int index = Integer.numberOfTrailingZeros(c);
//Do something...
b = b ^ c;
}
不是一个有效的答案,但要尊重你正在使用的技巧。我把它改成了b &= (b - 1)
.
int bitCount(int b) {
int bits = 0;
while (b != 0) {
int nextb = b & (b - 1); // Remove the rightmost bit 1
int power2ofBitIx = b ^ nextb; // Get the lost bit 10..0
int bitIx = bitCount(power2ofBitIx - 1); // And count 1..1
// Do something with bitIx
b = nextb;
++bits;
}
return bits;
}
阅读 Jerry Coffin 的回答。
您可以使用掩码获取 int 的设置位的位置并对每个位进行 AND 运算:
int c = 4128;
int two_32 = pow(2, 32);
for (int mask = 1, iter = 1; mask < two_32; mask <<= 1, iter++)
if (c & mask)
printf("Flag: %d set\n", iter);
这应该打印:
Flag: 0 set
Flag: 5 set
如果你要制作一个位棋盘游戏,你不应该需要位的位置,而是值。
我以前从未见过你的 while 循环,很好。我个人喜欢这个:
int tst = 255;
for(int looper = tst, i = Integer.highestOneBit(looper); looper != 0; looper &= ~i, i = Integer.highestOneBit(looper))
{
System.out.println(i);
}
公共布尔isBitSet(int位置){
int value = Integer.parseInt("0000000000000000000000000000000", 2);
BigInteger b = new BigInteger(String.valueOf(value));
b = b.setBit(4);
return b.testBit(4);
}