Чтение и сжатие Хаффманом 4-байтовой двоичной строки в среде STD C Linux

#c #linux #binary #compression #huffman-code

#c #linux #бинарный #сжатие #хаффман-код #двоичный

Вопрос:

Я работаю над некоторым домашним заданием по кодированию Хаффмана. У меня уже есть завершенный алгоритм Хаффмана, но мне нужно немного изменить его для работы с двоичными файлами. Я потратил некоторое время на чтение связанных проблем, и, возможно, из-за моего непонимания типов данных и двоичных файлов я все еще испытываю некоторые трудности, поэтому, надеюсь, я не повторяю предыдущий вопрос (я не буду публиковать код, связанный с частью программы Хаффмана).

Вот ключевая фраза: «Вы можете предположить, что каждый символ, который будет сопоставлен кодовому слову, представляет собой 4-байтовую двоичную строку.», и я думаю, что знаю, что Char представляет один байт, а unsigned int представляет четыре байта, поэтому я предполагаю, что я должен считывать входные данные по четыре байта за раз в буфер unsigned int, а затем собирать свои данные для части программы Хаффмана.

 int main() {
    unsigned int buffer;
    fstream input;
    input.open("test.txt", ios::in | ios::binary);


    while(input) {
        input.read(reinterpret_cast<char *>(amp;buffer), 4);
        //if buffer does not exist as unique symbol in collection of data add it
        //if buffer exists update statistics of symbol
    }
    input.close();
}
  

Похоже ли это на хороший способ обработки данных? Как я должен обрабатывать самый конец файла, если осталось всего 1,2 или 3 байта? Итак, тогда я просто сохраняю buffer как unsigned int в структуре. Просто из любопытства, как бы мне преобразовать buffer в строку символов?
Редактировать: каков наилучший способ сохранить заголовок файла, сжатого Хаффманом?

Ответ №1:

Похоже ли это на хороший способ обработки данных?

Вместо приведения указателя я бы предложил использовать union of int и char [4] и передать указатель на char массив, как и положено. Не знаю, какова остальная логика, поэтому не могу сказать, правильно ли выполнена фактическая обработка (которой нет в опубликованном вами коде), но мне это кажется довольно тривиальным.

Как я должен обрабатывать самый конец файла, если осталось всего 1,2 или 3 байта?

Предполагая, что каждый символ имеет длину 4 байта, я бы ожидал, что это недопустимый ввод.

Итак, тогда я просто сохраняю buffer как unsigned int в структуре. Просто из любопытства, как бы мне преобразовать buffer в строку символов?

Зачем вам это делать? В ваших данных «символ» равен 4 байтам. Но вы можете просто использовать приведение к массиву байтов, если хотите (или, лучше, использовать побитовые операции для извлечения фактических байтов, если порядок имеет значение).

Комментарии:

1. 1, я бы дал тот же ответ. Однако я все еще не уверен, всегда ли union гарантируется соответствие int и char[4] в определенном порядке.

2. Хорошо, это имеет смысл, одна вещь, которую я не понимаю, и я жду ответа TA, почему 4 байта? Поскольку они не предоставляют никаких тестовых данных, они говорят, что вы просто тестируете это с помощью и pdf, file и т.д., Но если размер неравномерно делится на 4, то это не сработает, верно? Или я что-то упускаю?

3. На самом деле это немного отличается от того, что я думал, TA хочет, чтобы мы группировали их как 4 байта, но если последний равен 1, 2 или 3 байтам, то все равно обрабатываем его, потому что он должен обрабатываться как допустимый ввод.

4. @MCH: если у вас не выровненный ввод, то вам нужно найти способ запомнить общий размер, а затем выровнять его и добавить в дерево. При распаковке, исходя из общего размера, удаляются последние лишние байты.