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