假设我们在Java中有两个BitSet对象,其值为
//<MSB....LSB>
B1:<11000101>
B2:<10111101>
我们如何比较B1和B2,知道 B1表示的值大于B2 表示的值。
是否为BitSet重载逻辑运算符(&gt;,&lt;,==)?或者我是否必须编写自己的实现?
更新:刚发现&#34;运营商&gt;未定义参数类型java.util.BitSet,java.util.BitSet&#34; 。有没有内置的方法呢?
答案 0 :(得分:7)
您可以通过xor
将两个集合放在一起,并将结果的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;
}
答案 1 :(得分:1)
不,操作符不会超载,因为a)Java中没有运算符重载,b)您的期望是错误和不合逻辑的。
BitSet就像名称表示一组位一样。你无法分辨出“更大”和“更小”的设置 - 就像说一种颜色比另一种颜色“更大”。如果你想比较位集,你必须创建一个比较指标 - 我想你想要的是比较从位创建的整数的值 - 如果是这种情况,请使用例如的代码BitSet to and from integer/long,然后致电
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()
和&amp; (特别是)BitSet#length()
不是您对比特操作所期望的轻量级操作,主要是由于recalculateWordsInUse();
,checkInvariants();
&amp; Long.numberOfLeadingZeros()
中使用了{{1}}。总而言之,除了本机整数使用之外的所有方法(尤其是如上所示的任何比较代码)都会在任何与性能相关的场景中导致严重的性能损失。
答案 2 :(得分:1)
您可以使用基于位的逻辑运算符(从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;
}
}