8

痛々しいほど明白な何かが欠けていますか?それとも、世界中の誰も実際にjava.util.BitSetを使用していませんか?

次のテストは失敗します。

@Test
public void testBitSet() throws Exception {
    BitSet b = new BitSet();
    b.set(0, true);
    b.set(1, false);
    assertEquals(2, b.length());
}

長さが2で値が10のBitSetになっていない理由は、私にはよくわかりません。java.util.BitSetのソースを調べたところ、ちょっと調べてみると、ビットを十分に区別できないようです。これはfalseに設定されており、ビットはどの値にも設定されていません...

(コンストラクターでビットセットのサイズを明示的に設定しても効果がないことに注意してください。例:

BitSet b = new BitSet(2);
4

6 に答える 6

9

(「1に設定」のように)最も高いビットセットはビット0です。したがって、長さは1である必要があります。

長さについては、JavaDocを参照してください。

public int length()

このビットセットの「論理サイズ」を返します。ビットセットの最上位セットビットのインデックスに1を加えたものです。BitSetに設定ビットが含まれていない場合はゼロを返します。

ビットが特定の解像度(たとえば16ビット境界)で割り当てられている場合、2より大きい可能性がありますが、サイズを探しているのではないでしょうか。

于 2010-05-18T01:43:36.987 に答える
6

人々は使用しますBitSet; しかし、彼らはあなたが意図したもの以外の何かのためにそれを使用します。BitSet非常にコンパクトでメモリ効率の高い形式でSet<Integer>、負の数を入れることができないという独特の特性を備えていると考えるのがおそらく最善でしょう。

BitSetのパターンでそれらを使用することはsで非常に一般的です

for (int id = set.nextSetBit(0); id >= 0; id = set.nextSetBit(id + 1)) {
  // do stuff to a set index
}

あなたがそれらを埋めるために何かをした後。これは、の要素を反復処理することと同じSetです。

于 2010-05-18T02:21:23.557 に答える
4

これも私を困惑させました。BitSetの現在のかなり予想外の機能の背後にある理論的根拠はわかりません。ただし、これは最終的なものではないため、いくつかの採用および拡張戦術を使用し、次のようにして、期待どおりの長さのセマンティクスを持つ固定ビットセットを取得できます。

import java.util.BitSet;

/**
 * Variation of BitSet which does NOT interpret the highest bit synonymous with
 * its length.
 *
 * @author casper.bang@gmail.com
 */
public class FixedBitSet extends BitSet{

    int fixedLength;

    public FixedBitSet(int fixedLength){
        super(fixedLength);
        this.fixedLength = fixedLength;
    }

    @Override
    public int length() {
        return fixedLength;
    }
}
于 2010-09-20T21:10:16.417 に答える
2

ビットセットがlong[]によってサポートされている場合、最小サイズは64です(1つのlongは64ビットであるため)。サイズは64の倍数で増加し、何らかの理由で、intを受け取るコンストラクターを使用するときに表現しようとしたビット数を維持していません。

于 2010-08-28T22:39:41.027 に答える
1

// Abhay Dandekar

import java.util.BitSet;

public class TestBitSet {

    public static void main(String[] args) {

        BitSet bitSet = new BitSet();
        System.out.println("State 0 : " + bitSet.size() + " : " + bitSet.length() );

        bitSet.set(0, true);
        bitSet.set(1, true);
        System.out.println("State 1 : " + bitSet.size() + " : " + bitSet.length() );

        bitSet.set(2, false);
        bitSet.set(3, false);
        System.out.println("State 2 : " + bitSet.size() + " : " + bitSet.length() );

        bitSet.set(4, true);
        System.out.println("State 3 : " + bitSet.size() + " : " + bitSet.length() );

    }
}

内部で何が起こっているかを示す単純なJavaプログラム。注意すべきいくつかのポイント:

  1. BitSetは長いによって支えられています

  2. デフォルト値はすべてfalseです

  3. 長さを返すときに、セット内で最も高い「真の」値のindex+1を返します。

以下の出力はそれ自体を説明できるはずです:

State 0 : 64 : 0

State 1 : 64 : 2

State 2 : 64 : 2

State 3 : 64 : 5

したがって、結論としてポイント:

  1. 変更されたビット数を結論付けるために長さを使用しないでください

  2. ブルームフィルターなどのシナリオで使用できます。ブルームフィルターの詳細はグーグルで検索できます..;)

お役に立てれば

よろしく、

アバイ・ダンデカー

于 2014-04-18T06:59:41.887 に答える
0

グッドキャスパー!あなたの小さな改善は確かに元のBitSetjavadefに存在するはずです!これもお勧めします(append()とconcat()はさまざまな使用法に役立ちます)

import java.util.BitSet;

public class fixBitSet extends BitSet {

  public int fsize = 0;

  public void set(int k, boolean value) {
    if (k >= fsize)
      fsize = k + 1;
    super.set(k, value);
  }

  public void append(fixBitSet bs) {
    for (int k = 0; k < bs.fsize; k++)
      super.set(fsize + k, bs.get(k));
    fsize += bs.fsize;
  }

  public static fixBitSet concat(fixBitSet[] vbs) {
    final fixBitSet bs = new fixBitSet();
    for (fixBitSet xbs : vbs)
      bs.append(xbs);
    return (bs);
  }

}
于 2014-01-22T06:58:26.187 に答える