我正在努力找到实现这一目标的正确方法: 想象一下,我们有一组位集如下:
00100
00101
10000
00010
10001
我想测试一下,哪些位只在所有位集中设置一次。在示例中,结果将是:
00010
因为第4位是唯一一个在所有系列中只出现一次的位。
通过按位逻辑运算,哪种方法最好?
提前致谢。
答案 0 :(得分:10)
正如您所看到的,您无法使用单个集合来存储中间结果,因为您需要区分每个位的3个状态:从不设置,设置一次并设置多次。
因此,您至少需要2个中间结果。例如,您可以跟踪至少设置一次的位和多次分别设置的位:
int atLeastOnce = 0;
int moreThanOnce = 0;
for (int current: sets) {
moreThanOnce |= (atLeastOnce & current);
atLeastOnce |= current;
}
int justOnce = atLeastOnce & ~moreThanOnce;
或者使用BitSet
s(它看起来不那么优雅,因为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;
答案 1 :(得分:4)
您可以使用一次两次的方法:
once
集合中
twice
集once
集once
- twice
这里的技巧是它可以并行执行:
C
twice
:= twice
或(once
AND C
)once
:= once
或C
实施可能如下:
BitSet 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;
答案 2 :(得分:1)
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