2011-12-27 3 views
2

Я пытаюсь записать дерево Хаффмана в сжатый файл после того, как все фактические данные сжатого файла были вставлены. Но я просто понял, что проблема, предположим, я решил, что как только все мои фактические данные будут записаны в файл, я поставлю два символа перевода строки и затем напишу дерево. Это означает, что когда я читаю материал назад, эти два перевода строки (или любой символ на самом деле) являются моими разделителями. Проблема в том, что вполне возможно, что фактические данные также имеют 2 строки, один за другим, в таком сценарии моя проверка ограничителя завершится неудачей. Здесь я привел пример двух строк, но то же самое верно для любой символьной строки, я мог бы подорвать проблему, возможно, взяв более длинную строку в качестве разделителя, но это имело бы два отрицательных эффекта: 1. Существует все же удаленная вероятность того, что длинная строка по некоторым совпадениям присутствует в сжатых данных. 2. Не обязательно раздувание файла, который необходимо сжать.Запись дерева huffman в файл после сжатия

Есть ли у кого-нибудь предложения по разделению сжатых данных из данных дерева?

ответ

3

Сначала напишите размер дерева в байтах. Затем напишите само дерево, а затем самое содержимое.

При чтении сначала читайте размер, затем дерево (теперь вы знаете, сколько символов нужно читать), а затем содержимое.

Размер может быть записан в виде строки, заканчивающейся подачей строки. Таким образом, вы знаете, что первые числа и линии относятся к размеру дерева.

+0

Это то, что я думал о том, чтобы делать изначально, но проблема в том, что дерево может быть огромным! Поэтому мне нужно написать Integer, это 4 байта прямо там! И если я пишу его как строку символов, я использую один байт для каждого целого числа, которое я вставляю туда. Не очень эффективна для программы, которая пытается сжать материал, экономя 2 или 3 бита за раз. – angryInsomniac

+0

Насколько велика вы ожидаете, что будет дерево? Несколько килобайт? – Giorgio

+0

@angryInsomniac Это еще хуже - размер (tree) + size (compress_data) 'может быть больше, чем' size (original_data) ', при правильных условиях. Очевидно, что это имеет смысл только в том случае, если ваш алфавит невелик и данные огромны (неравномерно распределены). Если вас интересует минимальное количество бит связи (при учете словаря), существует большое теоретическое информационное поле (открытое) исследование, называемое Communication Complexity :) – user1071136

0

Почему бы не написать размер и длину на первые 8 байтов (по 4 каждый), а затем на данные? Тогда что-то вроде:

uint32_t compressed_size; 
uint32_t data_len; 
char * data; 

file.read((char*)compressed_size, 4); 
file.read((char*)data_len, 4); 
data = new char[data_len]; 
zip.read(data, data_len); 

Должно работать. Вы можете сфотографировать данные для лучшего сжатия.