У меня есть огромный набор битов, представляющий все биты файла размером 74 МБ. Я использую алгоритм сжатия для создания сжатого строкового представления этого набора битов. Затем мне нужно сохранить эту строку в другой динамический набор битов, чтобы впоследствии ее можно было распаковать. Моя проблема в том, что независимо от того, как я пытаюсь заполнить набор битов из строки, он всегда заполняется в обратном порядке.
Ради простоты, скажем, моя сжатая строка
1110001101010111011101
Вот моя первая попытка заполнения динамического набора выходных данных:
string compressed = 1110001101010111011101;
output = boost::dynamic_bitset<unsigned char> (compressed);
Когда я делаю это, мой набор битов превращается в обратную строку:
1011101110101011000111
Итак, я попробовал это:
output = boost::dynamic_bitset<unsigned char> (compressed.begin(), compressed.end());
И я получаю точно такой же вывод. Затем я попытался использовать обратные итераторы, и я понятия не имею, как это возможно, но он заполняет набор битов точно так же:
output = boost::dynamic_bitset<unsigned char> (compressed.rbegin(), compressed.rend());
Единственный способ, которым я могу заполнить свой набор битов в правильном порядке, это сделать это:
for(uint i = 0; i < compressed.size(); i++)
{
if(compressed[i] == '0')
output.push_back(false);
else output.push_back(true);
}
Это заполняет мой выходной набор битов в правильном порядке, однако это значительно медленнее, чем при использовании другого метода (на 30 секунд медленнее с используемой строкой). Я также могу использовать std :: reverse, чтобы перевернуть строку на месте, а затем заполнить набор битов, но это займет МНОГО дополнительного времени. Есть ли способ эффективно заполнить динамический набор битов значениями из строки в обычном порядке? Я понимаю, почему он заполнен в обратном порядке, но я не использую свой набор битов для представления целого числа, я использую его для хранения данных из файла, поэтому мне нужно, чтобы он был в порядке. Однако не имеет смысла, почему использование обратных итераторов даст тот же результат.
РЕДАКТИРОВАТЬ
Я сделал скриншот своего вывода и соответствующей части моего кода. Сжатый вывод показывает первые 6000 символов сжатой версии моего набора битов, сохраненной в виде строки. Эта строка сама по себе не имеет проблем. Подчеркнута красным линия, которую я использую для хранения этой строки в выходных данных boost :: dynamic_bitset. Затем я печатаю первые 6000 символов выходного набора битов, и они совершенно разные. Следует отметить, что битовый набор «output» передается в эту функцию в качестве ссылочного параметра, но изначально он пуст.
в документация std::string
конструктор boost::dynamic_bitset
назначит последний символ ввода младшему значащему биту, который будет битом с индексом 0
,
Чтение его в цикле с растущим индексом даст исходную строку в обратном порядке.
Конструкторы из итераторов сделают что-то совершенно другое. Они интерпретируют каждый символ как целое число (код символа) и сохраняют двоичное представление для каждого целого числа в наборе битов.
Учитывая, что, например, оператор вывода потока для dynamic_bitset
Я буду печатать набор, начиная с самого старшего значащего, думаю, нет проблем с его сохранением. Просто не забудьте учесть это, если вы используете петли. Однако, таких циклов, вероятно, следует избегать, поскольку доступ к отдельным битам будет медленнее, чем работа с целыми блоками хранения одновременно. Использование собственного размера блока вместо unsigned char
вероятно, было бы целесообразно по той же причине.
Если вам действительно нужно сохранить в другом порядке, сначала переверните строку:
std::reverse(compressed.begin(), compressed.end());
Других решений пока нет …