2012-02-01 37 views
12

これらが欠落している特定の理由はありますか?Javaの `BitSet`に` shiftLeft`と `shiftRight`関数がないのはなぜですか?

これらは、BigIntegerに存在しますが、変更可能なデザインパターンがBigIntegerのため、通常は非常に遅いです。 BitSetは、それが変更可能であるためにはるかに良いですが、私は実際にshift関数(<<>>>longのs)を逃しています。 BitSetについては、インプレースシフトも循環回転と同様に有用であろう。

私はShifting a Java BitSetget(off, len)をシフトに使用していますが、これはコピーが必要です)への返信を見ました。

間違ってはいけません。私はバグを報告する場所を知っています。私はちょうどある特定の理由がある場合は除外するためにかどうか疑問に思っています。いくつかのデザインパターンまたはそのような概念。特には、BigIntegerに含まれるです。

+0

「セット」なので、「文字列」ではありません。 – bmargulies

+1

@bmargulies: 'long'も文字列ではありません。それにもかかわらず、シフト演算子があります。そして 'String'は実際にはありません。そして、 'get(i、j)'セマンティクスは基本的に 'substring'と一致し、' long'では利用できません。 –

+0

'set'は '* unordered * collection'を意味します。 BitSetは、2のどの累乗がオンになっているかを知っていますが、シャッフルしているわけではありません。 – bmargulies

答えて

9

概念的には、BitSetは、セット内の各ビットが特定の意味を持つように、多くの設定をトラッキングするために使用されます。シフト操作は、その意味ではほとんど意味がありません。

BitSetの別の有用な目的をはっきりと見つけましたが、それはBitSetがおそらく想定されていた範囲外です。

+1

[docs](http://docs.oracle.com/javase/6/docs/api/java/util/BitSet.html)から引用すると、BitSetは_ "必要に応じて増加するビットのベクトルとして構想されました"これはあなたが提案する典型的な使用よりもはるかに一般的です。他のベクトルクラス(Vector、ArrayListなど)には「シフト」操作はありませんが、同じことを効果的に行う「挿入」と「削除」操作があります。 BitSetにも同様の機能を持たせることは理にかなっていますが、そうではありません。 –

+0

(順不同の) 'set'ポイントは、それが幾分非合理的に使用されることを除いて、良いです。ありがとうございました。 –

+0

BitSetは設定用のビューであると私は質問します。私が設定をしているのであれば、私はint/longのビットを使うか、20年前に "本当のプログラマ"のように:-)、より適切にはEnumとEnumSetを使用します。私は、BitSetをより疎/コンパクトな 'Set 'として使う傾向があります。 – user949300

1

私の推測では、コードのやり方が複雑になると思います。たとえば、「3で左シフト」した場合、-3のフィールド(シフト3)を追加することができます(または、3、私は50%の確率しか得られません:-)。また、get()メソッドとset()メソッドでは、shiftでbitIndexを調整するだけでコードが機能します。例えば

public boolean get(int bitIndex) { 
    bitIndex += shift; // new code!!! 
    if (bitIndex < 0) 
     throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex); 

    checkInvariants(); 

    int wordIndex = wordIndex(bitIndex); 
    return (wordIndex < wordsInUse) 
     && ((words[wordIndex] & (1L << bitIndex)) != 0); 
    } 

しかし、intersects()やor()のようないくつかの操作では、コードが本当に乱雑になり始めます。両方のビット集合が可能なシフトが、これは速い厄介になるだろうしていた場合

// Perform logical OR on words in common 
    for (int i = 0; i < wordsInCommon; i++) 
     words[i] |= set.words[i]; 

    // Copy any remaining words 
    if (wordsInCommon < set.wordsInUse) 
    System.arraycopy(set.words, wordsInCommon, 
        words, wordsInCommon, 
       wordsInUse - wordsInCommon); 

:今か()メソッドのコアは非常にシンプルで早いのが特長です。彼らはおそらくあなたがシフトしたいなら、getとcopyを使うべきだと考えたでしょう。

get()で私を驚かせたことの1つは、1L << bitIndex&31です。明らかに< <ループがあります。これで、私は遠くの機械語を覚えています。

+1

はい、私はそれをすることを考えました。しかし、私は本当に「または」と「xor」が必要でした。 Javaは実際には 'BigInteger'の' int [] 'にシフトするコードを持っていますし、' long [] 'の' BitSet'にかなりコピーできます。それほど大きな違いはありません。 –

関連する問題