我正在尝试找到正确的方法来实现这个目标:
假设我们有一个位集合组如下:
00100
00101
10000
00010
10001
我想测试哪些二进制位在所有的位集合中只被设置一次。例如,结果应该是:
00010
由于第4位是所有系列中唯一只出现一次的位,因此进行按位逻辑操作的最佳方法是什么?
提前致谢。
我正在尝试找到正确的方法来实现这个目标:
假设我们有一个位集合组如下:
00100
00101
10000
00010
10001
我想测试哪些二进制位在所有的位集合中只被设置一次。例如,结果应该是:
00010
由于第4位是所有系列中唯一只出现一次的位,因此进行按位逻辑操作的最佳方法是什么?
提前致谢。
你可以看到,你不能使用一个单独的集合来存储中间结果,因为你需要区分每个位的三种状态:从未设置、设置一次和设置多次。
因此,你至少需要两个中间结果。例如,你可以分别跟踪至少设置了一次和设置了多次的位:
int atLeastOnce = 0;
int moreThanOnce = 0;
for (int current: sets) {
moreThanOnce |= (atLeastOnce & current);
atLeastOnce |= current;
}
int justOnce = atLeastOnce & ~moreThanOnce;
或者使用BitSet
(看起来不那么优雅,因为BitSet
是可变的):
BitSet atLeastOnce = new BitSet();
BitSet moreThanOnce = new BitSet();
for (BitSet current: sets) {
BitSet moreThanOnceInCurrent = (BitSet) atLeastOnce.clone();
moreThanOnceInCurrent.and(current);
moreThanOnce.or(moreThanOnceInCurrent);
atLeastOnce.or(current);
}
atLeastOnce.andNot(moreThanOnce);
BitSet justOnce = atLeastOnce;
exactlyOnce
而不是atLeastOnce
,但你的解决方案肯定更干净。 - Vincent van der Weeleint
替换为 BitSet
,或者假设一个抽象模型,其中 int
是任意长的。 - nneonneoBitSet once = new BitSet();
BitSet twice = new BitSet();
for(BitSet b : sets){
BitSet mask = (BitSet) b.clone();
mask.and(once);
twice.or(mask);
once.or(b);
}
once.andNot(twice);
return once;
int length = 5;
int count[] = new int[length];
for (i = 0; i < bitset.length(); i++) {
int value = bitset[i];
unsigned int count = 0;
for (int j = 0; j < length; j++) { // until all bits are zero
if ((value & 1) == 1) // check lower bit
count[j]++;
value >>= 1; // shift bits, removing lower bit
}
}
int number = 00000;
for (int k = 0; k < 5; k++) {
if (count[k] == 1)
number = number | 1;
number >>= 1;
}
number is desired answer