簡體   English   中英

Java:BitSet比較

[英]Java: BitSet comparison

假設我們在Java中有兩個BitSet對象,其值為

//<MSB....LSB>
B1:<11000101>
B2:<10111101>

我們如何比較B1和B2才能知道B1代表的值大於B2代表的值。

是否為BitSet重載了邏輯運算符(>,<,==) 或者我是否必須編寫自己的實現?

更新:剛發現“運算符>未定義參數類型java.util.BitSet,java.util.BitSet” 有沒有內置方法可以這樣做?

你可以通過xor -ing兩個集合,並將結果的長度與位集的length進行比較來實現:

  • 如果xor為空,則位集相等。 您可以通過調用equals()來繞過此操作
  • 否則, xor結果的長度將等於兩個值之間不同的最高有效位的位置。
  • 這個位設置的兩個操作數中的哪一個是兩者中較大的一個。

這是一個示例實現:

int compare(BitSet lhs, BitSet rhs) {
    if (lhs.equals(rhs)) return 0;
    BitSet xor = (BitSet)lhs.clone();
    xor.xor(rhs);
    int firstDifferent = xor.length()-1;
    if(firstDifferent==-1)
            return 0;

    return rhs.get(firstDifferent) ? 1 : -1;
}

演示。

不,運算符沒有超載,因為a)Java中沒有運算符重載,b)你期望的是錯誤和不合邏輯的。

BitSet就像名稱表示一組位 你無法分辨出“更大”和“更小”的設置 - 就像說一種顏色比另一種顏色“更大”。 如果你想比較位集,你必須創建一個比較指標 - 我想你想要的是比較從位創建的整數的值 - 如果是這種情況,使用例如BitSet的代碼到整數/長 ,然后打電話

static int compare( BitSet bs1, BitSet bs2 ) {
  return Long.compare(Bits.convert(bs1),Bits.convert(bs2));
}

或者,作為Comparator

class BitSetComparator implements Comparator<BitSet> {
  int compare( BitSet bs1, BitSet bs2 ) {
    return Long.compare(Bits.convert(bs1),Bits.convert(bs2));
  }
}

請注意,在這種特殊情況下,兩個集合必須適合long (最多63位)。 或者,假設您的度量標准是“具有更高無符號整數表示的集合更大”,您可以使用XORing,或循環遍歷位或任何其他通過所有位的構造 -

int compare( BitSet bs1, BitSet bs2 ) {
  BitSet x = ((BitSet)bs1.clone()).xor(bs2);
  return ( x.isEmpty() ) ? 0 : ( x.length() == bs2.length() ? 1 : -1 );
}

但在所有這些情況下 ,如果你的目標是比較你的位,最好的辦法就是用long來存儲你的數據,然后使用https://docs.oracle.com/javase直接將它作為無符號值進行比較。 /8/docs/api/java/lang/Long.html#compareUnsigned-long-long- - 否則你通過往復轉換來處理基於案例的情況,從而失去了位存儲的時空效率使用類不是為了它而設計的。 BitSet#xor()和(特別是) BitSet#length()都不是比特操作所期望的輕量級操作,主要是由於recalculateWordsInUse(); checkInvariants(); Long.numberOfLeadingZeros()在其中使用。 總而言之,除了本機整數使用之外的所有方法(尤其是如上所示的任何比較代碼)都會在任何依賴於性能的場景中導致嚴重的性能損失。

您可以在位的基礎上使用邏輯運算符(從get()接收的布爾值):

// Assumed equal length
boolean less(BitSet b1, BitSet b2) {
 int N = b1.length();

 for (int i = N-1; i >= 0; i--) {
    if (b1.get(i) ^ b2.get(i)) return b2.get(i);
 }

 return false;
}

或者你可以有一個比較器:

class BitsComparator implements Comparator<BitSet> {
  @Override
  int compare (BitSet b1, BitSet b2) {
    if (b1.length() > b2.length())
       return 1;
    if (b1.length() == b2.length()) {
      int N = b1.length();
      for (int i = N-1; i >= 0; i--) {
        if ((b1.get(i) ^ b2.get(i)) && b2.get(i)) return -1;
      }
      return 0;
    }
    return -1;
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM