【问题标题】:Get all Indexes of the set bits in a BitSet获取 BitSet 中设置位的所有索引
【发布时间】:2013-03-01 16:39:33
【问题描述】:

我正在寻找一种快速算法,它可以为我提供 BitSet 对象中设置位的所有索引。 这很慢:

BitSet bitSet = ...
Collection<Integer> indexes = new ArrayList<Integer>(bitSet.cardinality());
int nextSetBit = bitSet.nextSetBit(0);
for (int i = 0; i < bitSet.cardinality(); ++i ) {
    indexes.add(nextSetBit);
    nextSetBit = bitSet.nextSetBit(nextSetBit + 1);
}
...

感谢任何帮助!

【问题讨论】:

标签: java bitset


【解决方案1】:

根本不需要使用bitSet.cardinality()

for (int i = bitSet.nextSetBit(0); i != -1; i = bitSet.nextSetBit(i + 1)) {
    indexes.add(i);
}

【讨论】:

    【解决方案2】:

    BitSet#nextSetBit(int) javadocs 中所述:

    //To iterate over the true bits in a BitSet, use the following loop:
    for (int i = bs.nextSetBit(0); i >= 0; i = bs.nextSetBit(i+1)) {
         // operate on index i here
         if (i == Integer.MAX_VALUE) {
             break; // or (i+1) would overflow
         }
     }
    

    【讨论】:

      【解决方案3】:

      从 Java 8 开始,您可以使用 BitSet 的 stream() 方法。

      IntStream 流()

      返回此 BitSet 包含处于设置状态的位的索引流。

      【讨论】:

        【解决方案4】:

        更改循环(将复杂度增加到 O(N^2),因为您在每次循环迭代中调用 cardinality()):

        for (int e = bitSet.cardinality(), i = 0; i < e; ++i ) {
            indexes.add(nextSetBit);
            nextSetBit = bitSet.nextSetBit(nextSetBit + 1);
        }
        

        【讨论】:

        • @myborobudur 如果它对您感知的缓慢没有帮助,很可能不是由 BitSet 引起的(它太小没关系 i> 到 Integer 的自动装箱远远超过了它)。使用分析器进行测量。
        • 最好使用不调用cardinality()的方案
        猜你喜欢
        • 2016-07-08
        • 1970-01-01
        • 2011-06-08
        • 1970-01-01
        • 2012-04-15
        • 2013-02-10
        • 1970-01-01
        • 2022-11-29
        相关资源
        最近更新 更多