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