繁体   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