[英]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.