2017-01-24 5 views
0

Я искал в Интернете, но не смог найти то, что мне нужно.Дерево Хаффмана для больших файлов

Мне нужно сжать большие файлы, используя кодировку Хаффмана. Моя идея состояла в том, чтобы прочитать первую 1-2 файла

(чтобы избежать первого чтения всего файла, чтобы построить дерево, а затем читать его еще раз, чтобы кодировать его, избегая O (2n)),

и построить дерево Хаффмана. Если какой-либо из 256 байтов алфавита отсутствует, я бы добавил его сам, если он появится позже в файле (а не в первых 1-2 МБ). Но пытаться проверить результат с помощью этого:

int * totalFr = new int[256]; 
unsigned char * symArr= new unsigned char[256]; 

for (int i = 0; i < 256; i++) 
{ 
    totalFr[i] = i; 
    symArr[i] = unsigned char(i); 
} 

int size = sizeof(symArr)/sizeof(symArr[0]); 
buildHuffmanTree(totalFr,symArr, size); 
delete[] totalFr; 
delete[] arrei; 

где buildHuffmanTree это функция, которая строит дерево Хаффмана, сделал мой Осознайте лучший символьный код, я мог бы получить было 7 битов, например 0000001.

И вот откуда мой вопрос пришел - стоит ли построить дерево Хаффмана для полного 256-буквенного алфавита? Или лучше использовать адаптивное кодирование Хаффмана для фрагментов, таких как 1-2MB

+0

delete [] не является C. Либо ваш тег является неправильным, либо у вас возникнут проблемы с компиляцией – UKMonkey

+0

Я делаю это на C++. Я отметил его 'C', потому что я думал, что это похоже, и люди предпочли бы мне использовать' std :: vector', а затем отвечая на вопрос об алгоритме. Теперь я не буду этого делать :) –

+0

Зависит полностью от данных файла. Если данные в остальной части файла «достаточно близки» к началу, то ваша идея работает. Если нет, то для каждой секции вы должны сделать другую таблицу. Попробуйте оба варианта в нескольких файлах. – stark

ответ

1

Вы не можете ожидать многого из кодирования Хаффмана, если данные не являются чрезвычайно предвзятыми относительно того, какие байты присутствуют. Я просто попробовал 100-килобайтный файл английского текста из Википедии. Он получил файл до 63% от его первоначального размера, поэтому, возможно, восемь бит до пяти бит в среднем. Также это делал Хаффман в блоках примерно по 16 КБ за раз, чтобы код был адаптирован к каждому блоку.

Нормальное сжатие zlib, которое также ищет соответствующие строки, снижает его до 35% от исходного размера. Более продвинутые компрессоры, такие как xz, которые тратят больше времени и памяти, все более и более ищущие для соответствия строк, а также немного лучше, чем кодирование Хаффмана, снижают его до 26% от исходного размера.

+0

Я был обеспокоен, если выполнение кодировки Хаффмана с полным набором заданных 256 слов может превышать исходный размер данных? Что вы имеете в виду, что дерево адаптировано для каждого блока размером 16 КБ? Что вы делаете нормальное кодирование Хаффмана и используете его для фрагментов размером 16 КБ, или вы использовали «адаптивный Хаффман» (и почему бы вы его обновить за 16 КБ, а не за 1 символ)? Спасибо заранее –

+0

Да, добавление символов, которые не отображаются, может привести к расширению вместо сжатия для других сжимаемых данных. Вместо этого вы должны сделать то, что делает zlib, что делает новый код Хаффмана для каждого блока данных. Время, затрачиваемое на вычисление нового кода и битов, необходимых для отправки описания кода, может быть достаточно малыми долями для достаточно больших блоков. –

+0

Так что мне нужно сериализовать дерево перед каждым куском, не так ли? Следовательно, нет способа избежать 'n' для создания дерева и еще одного' n' для его кодирования? –

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