Java:BitSet比较

时间:2014-12-06 11:28:22

标签: java bitset

假设我们在Java中有两个BitSet对象,其值为

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

我们如何比较B1和B2,知道 B1表示的值大于B2 表示的值。

是否为BitSet重载逻辑运算符(&gt;,&lt;,==)?或者我是否必须编写自己的实现?

更新:刚发现&#34;运营商&gt;未定义参数类型java.util.BitSet,java.util.BitSet&#34; 。有没有内置的方法呢?

3 个答案:

答案 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;
}

Demo.

答案 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;
  }
}