2014-10-02 7 views
2

Я хотел бы преобразовать строку, состоящую из 0 и 1 в массив бит.
Строка имеет длину ~ 30000 и разреженные (в основном 0s, несколько 1S)
Например, если строка
«00000000100000000010000100000000001000»
Я хотел бы, чтобы преобразовать его в массив битов, которые будут хранить
[00000000100000000010000100000000001000]Преобразование строки в массив бит

Я там думать об использовании BitSet или OpenBitSet ли лучше? Вариант использования - эффективный логический ИЛИ.

Я имею в виду вдоль этих линий

final OpenBitSet logicalOrResult = new OpenBitSet(); 
for (final String line : lines) { 

    final OpenBitSet myBitArray = new OpenBitSet(); 
    int pos = 0; 
    for (final char c : str.toCharArray()) { 
     myBitArray.set(pos) = c; 
     pos++; 
    } 
    logicalOrResult.or(myBitArray); 
} 
+0

@ StevenA.Lowe Это не так. – Tad

+0

@ StevenA.Lowe Это либо хороший вопрос, либо плохой. Почему вас это волнует, если это домашняя работа? –

+2

@AnubianNoob: если это домашнее задание, и я говорю OP ответ, тогда они ничего не узнали. см. http://meta.stackexchange.com/questions/18242/what-is-the-policy-here-on-homework для полуофициальной политики –

ответ

1

BitSet пробегающее значением между 0 и 30000 нуждается в long массиве размера меньше, чем 500, поэтому можно предположить, что BitSet.or (или соответствующий метод OpenBitSet) будет достаточно быстро, несмотря на разреженность. Похоже, что OpenBitSet имеет лучшую производительность, чем BitSet, но кроме этого на самом деле не имеет значения, что вы используете, обе будут эффективно реализовывать or. Однако обязательно передать длину строки в конструктор (Open)BitSet, чтобы избежать перераспределения внутреннего массива long во время строительства!

Если ваши строки гораздо больше, и ваша разреженность является экстремальной, вы могли бы также рассмотреть вопрос о хранении их в качестве отсортированного списка Integer с (или int с, если вы используете библиотеку как сокровищница), представляющую индексы, которые содержат 1 , Поразрядный or может быть реализован в режиме слияния (сортировки), что довольно эффективно (время O (n + m), где n, m - числа единиц в каждой строке). Я подозреваю, что в вашем сценарии он будет медленнее, чем подход BitSet.

+0

my BitSet будет располагаться над значениями 1 и 0 - не 0 и 30000. Это вы имеете в виду? – Tad

+1

№. Ваш 'BitSet' * представляет * набор целых чисел от 0 до некоторого верхнего предела. Например, бит 01001101 представляет набор {0, 2, 3, 6} - набор индексов, установленный в 1. Это также является представлением 'toString()' 'BitSet'. Поскольку ваши строки имеют длину ~ 30000, соответствующий набор 1-индексов находится в диапазоне значений от 0 до 30000. – misberner

0

Вы можете перебирать каждый символ:

boolean[] bits = new boolean[str.length]; 

for (int i=0;i<str.length;i++) { 
    if (str.charAt(i).equals("1") 
     bits[i] = true; 
    else if (str.charAt(i).equals("0") 
     bits[i] = false; 
} 

Если вы хотите быть эффективным памяти, вы можете попробовать RLE (Run Length Encoding).

+0

Мне нравится этот подход, но я прочитал в http://stackoverflow.com/questions/383551/what-is-size-of-a-boolean-variable-in-java, которая использует BitSet, имеет лучшую оптимизацию, чем массив логических.Я также рассматривал RLE, что было бы здорово, так как мой массив разрежен, но я не уверен, как делать логический ИЛИ на сжатом массиве. Думаю, мне нужно было сначала распаковать его, если только я не упустил что-то. – Tad

2

BigInteger может разобрать его и хранить его, и сделать битовые операции:

BigInteger x = new BigInteger(bitString, 2); 
BigInteger y = new BigInteger(otherBitString, 2); 
x = x.or(y); 
System.out.println(x.toString(2)); 
+0

Знаете ли вы, есть ли тесты BigInteger и OpenBitSet и BitSet (или любой другой библиотеки) для выполнения логического ИЛИ? – Tad

+0

@Tad Я не знаю, но вы можете легко сравнить их, выполнив тесты в рамках предполагаемого приложения. – Boann

Смежные вопросы