2014-12-06 2 views
2

Предположим, у нас есть два объекта BITSET в Java со значениями вJava: сравнение BitSet

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

Как мы можем сравнить B1 и B2, чтобы узнать, что значение, представленное B1 больше, чем на В2.

являются логическими операторами (>, <, ==) перегружены для BitSet? или мне нужно написать свою собственную реализацию?

Обновление: только что найдено, что «Оператор» не определен для типов аргументов java.util.BitSet, java.util.BitSet «. Есть ли встроенный способ сделать это?

+2

не существует перегрузка операторов в Java. вы можете написать функцию или использовать предопределенный интерфейс, например Comparable – Adem

ответ

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.

+0

Хороший метод для сравнения для равенства. Но я хотел найти больше BitSet. –

+0

@MangatRai Nope, это не сравнение для равенства - он сообщает вам, какой бит установлен больше, и он не сломается, когда у вас более 63 бит. – dasblinkenlight

+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() & (особенно) BitSet#length() - это не легкие операции, которые вы ожидаете от бит ops, в основном из-за recalculateWordsInUse();, checkInvariants(); & Long.numberOfLeadingZeros() Используется в них. В общем, все методы, кроме использования целого целого (особенно любой сравнительный код, как показано выше), приведут к серьезной потере производительности в любых сценариях, зависящих от производительности.

+0

. Вы можете использовать 'Long.compare()' – fge

+0

. Спасибо за объяснение, почему BitSet не имеет тип Comparable и способ преобразования в/из целого был очень изящным. –

+0

@fge IFTFY, хороший момент. – vaxquis

1

Вы можете использовать логический оператор на долото основе (логические значения, полученные от ГЭТ()):

// 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; 
    } 
} 
+0

Благодарим вас за ответ. Кстати, вы можете захотеть заменить x, y на b1, b2 соответственно ... –

+0

Да, исправлено. Извините, что :) –