你能在Java Bitset中获得一组连续的位吗?

时间:2013-12-18 18:54:57

标签: java bitset

我有一个BitSet,其中的信息如下所示:

00011110111110

是否有任何有效的方法可以获得例如设置的最大连续位数?在上面的示例中,它将是5。或者是位设置有效的循环?我只是想知道是否还有另一种更快的方式

2 个答案:

答案 0 :(得分:3)

对于n位组,有一个很好的算法,但它需要位移。也许可以使用BitSet.toLongArrayvalueOf(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,我们知道在此之前的任何运行都不能是最大运行。
  • 重复上述步骤。

这当然是最好的情况,次线性和最坏情况相当于将列表完全循环一次,因为我们从不会多次检查一个插槽。