我有一个BitSet
,其中的信息如下所示:
00011110111110
是否有任何有效的方法可以获得例如设置的最大连续位数?在上面的示例中,它将是5
。或者是位设置有效的循环?我只是想知道是否还有另一种更快的方式
答案 0 :(得分:3)
对于n位组,有一个很好的算法,但它需要位移。也许可以使用BitSet.toLongArray
和valueOf(long[])
。在不完整的代码中:
int maxNumberOfConsecutiveBits(BitSet bitSet) {
int maxLength = 0;
BitSet bs = bitSet.clone();
while (!bs.isEmpty()) {
++maxLength;
BitSet bs2 = shiftOne(bs);
bs.and(bs2);
}
return maxLength;
}
while循环将迭代到maxLength。
使用nextClearBit
遍历所有位0并且可能更快。
int maxNumberOfConsecutiveBits(BitSet bs) {
int maxLength = 0;
int onesI = bs.length(); // Points to the prior 0.
for (int i = onesI; (i = bs.previousClearBit(i - 1)) >= 0; ) {
int length = onesI - 1 - i;
maxLength = Math.max(maxLength, length);
i = bs.previousSetBit(i - 1) + 1; // Heuristic, optional.
onesI = i;
}
return maxLength;
}
就个人而言,我需要为两个解决方案计时 - 出乎意料。
答案 1 :(得分:0)
提出的算法:
假设我们处于BitSet
的中间,那么我们最长的运行时间是5.我们遇到了下一个1
。然后我们可以跳过四个位置。
1
,我们会一直持续到0.我们从原来的跳过点回溯,看看是否继续运行。如果运行小于最大值,则不执行任何操作。如果没有,我们将max run设置为run的长度。然后,在任何一种情况下,我们将下一个位置更改为0之后。0
,我们知道在此之前的任何运行都不能是最大运行。这当然是最好的情况,次线性和最坏情况相当于将列表完全循环一次,因为我们从不会多次检查一个插槽。