LZSS - абсолютно простая штука. Сжатые данные состоят из элементов двух типов. 1) часть несжатых данных в чистом виде. 2) данные которые имеют копию.

lzss0.cpp - почти простейший упаковщик. Чтобы понять суть достаточно посмотреть на процедуру распаковки.

lzss-t.cpp - дальнейшая постройка. Для поиска совпадения используется дерево с бинарным поиском. Поскольку у нас есть два вида ссылок, ближние и дальние. То используется два дерева, одно для ближних совпадений, другое для дальних. Деревья не балансируются. К сожалению, писав это я поддался ненужным стереотипам. Бинарное дерево в данном случае, совсем не эффективная и медленная структура.

lzss1.cpp - Уже рабочий вариант. Более правильный и более красивый с точки зрения логики исходник. Для работы использует префиксное дерево. Хотя тормозит по причине того что поиск букв в узлах, организован через линейный список. В тоже время скорость его мало зависит от характера данных. А поиск в узлах можно превратить в бинарный. Так же есть куча простора для укорения самого алгоритма и технических приёмов... Используется два вида ссылок, и счётчик для обозначения несжатых данных.

lzss2.cpp - Второй вариант с более сильным сжатием, но немного более медленный. По сжатию мне каким-то образом даже удавалось обгонять с его помощью ZIP. Практика показала что если 3 байта, это минимальныq размер повторения. То данные которые хоть немного сжимаются в основном содержат 2-3 байта уникальных данных. Поэтому использовать счётчик уникальных данных расточительно. Так же не смысла отводить под него меньше разрядов (по два бита для 2-3 байт, это много). Поэтому каждый уникальный байт обозначается одним битом. Разрядность всех счётчиков можно изменить. Распаковка использует побитовое чтение данных. Поэтому тоже работает чуть медленней (с незаметной разницей).

Hosted by uCoz