Вы находитесь на странице: 1из 6

3.3.

Алгоритм LZ78

В отличие от LZ 77, алгоритм LZ 78 не использует


скользящее окно буфер поиска, упреждающий буфер.
Вместо этого он по мере обработки выходного файла
динамически строит в явном виде словарь – (первона-
чально пустой), содержащий пронумерованный список
максимально коротких не встречавшихся в тексте ранее
цепочек символов. Его размер ограничен только объе-
мом доступной памяти.
Первый символ словаря (с номером 0) – ”пустой“
символ. Алгоритм считывает последовательно символы
сообщения до тех пор, пока накапливаемая подстрока
совпадает с одной из уже имеющихся в словаре фраз.
Как только эта подстрока перестанет соответствовать
хотя бы одной фразе словаря, алгоритм генерирует
код, состоящий из двух полей: 1 – индекса (номера) той
строки в словаре, которая до последнего введенного
символа совпадала с текущей обрабатываемой под-
строкой; 2 – последнего введенного символа, нару-
шившего совпадение. Затем эта введенная подстрока
добавляется в словарь.
Как было сказано, словарь вначале содержит лишь
пустую строку в позиции 0. По мере поступления и ко-
дирования символов добавляются новые подстроки в
позиции 1, 2 и т.д. Когда некоторый следующий символ
X читается из входного файла, то в словаре ищется
подстрока из одного символа X . Если такой подстроки
нет, то на выход кодера подается код (0, X) , а символ
X добавляется в словарь. Если символ x уже есть в
словаре, например, в позиции 24, то читается следую-
щий символ входного файла, например Z , а в словаре
ищется двухсимвольная подстрока XZ . Если таковая
не найдена, то в словарь записывается новая подстро-
ка XZ , а на выход поступает код (24, Z) , где 24 –
1
указатель номера позиции символа X в словаре.
Если строка XZ уже есть в словаре, продолжается
чтение новых символов и их присоединение к текущей
строке и т.д. до тех пор, пока в некоторый момент такой
новой строки в словаре уже не находится. Тогда кодер
добавляет ее в словарь и выдает двухэлементный код,
в первом поле которого стоит номер последней
найденной в словаре строки, а во втором поле записан
последний символ новой подстроки, на котором и
нарушено совпадение с существовавшими в словаре
фразами. В процессе обработки входного файла сло-
варь формируется, начиная с коротких строк, а затем
уже добавляются все более длинные строки. Чем
большим становится размер словаря, тем более глубо-
кий поиск длинных совпадающих подстрок можно про-
вести, но при этом увеличивается длительность сло-
варного поиска, а также длина поля указателей (длина
метки позиции префикса новой подстроки).
В случае, если размер формируемого словаря ис-
черпал объем доступной памяти, возможны следующие
способы решения проблемы:
- словарь ”замораживается“, т.е. из него не удаляются
старые и в него не вносятся новые записи;
- удаляются все записи, и начинает строиться новый
словарь;
- из заполненного словаря удаляются некоторые са-
мые старые и наименее часто используемые записи,
чтобы освободить место для новых записей.
Таким образом, резюмируя вышесказанное, рабо-
ту алгоритма можно кратко описать следующим обра-
зом:
1. Входной поток символов разбивается на макси-
мально короткие ранее не встречавшиеся цепочки.
2. Полученные цепочки заносятся в словарь и нуме-
руются.

2
3. Префикс (все символы, кроме последнего) каждой
цепочки ищется в словаре и строится двухэлементный
код, на первой позиции которого располагается индекс
(порядковый номер в словаре) префикса, а на второй –
последний символ цепочки.
Сжатый файл представляет собой последователь-
ность кодов каждой из обработанных кодером цепочек
символов входного файла.

Пример 8.12. Закодировать с помощью алгоритма


LZ78 тот же текст “ LZ 77LZ 77 ”, что и в примере 8.11.

Решение:
а) Кодирование
Легко видеть, что этот текст можно разбить на
следующую последовательность ранее не встречав-
шихся при его чтение цепочек: “ L ”, ” Z ”, ” 7 ”, ” 7L ”, ” Z7 ”,
” 7. ”, которые и будут последовательно вводиться в
словарь и кодироваться. Рассмотрим этот процесс по
шагам.
1. В исходном состояний словарь содержит только
одну пустую строку в позиции под номером 0. Произво-
дится чтение первого символа ” L ” входного файла.
Производится его поиск в словаре. Поскольку он отсут-
ствует, то производится запись символа L в словарь в
позиции под номером 1 и формирование на выходе ко-
да (0, L) .
2. Считывается следующий символ Z текста и, ввиду
его отсутствия в словаре, он вносится в словарь на по-
зиции с номером 2 и формируется выходной код (0, Z) .
3. Читается очередной символ 7 текста, проверяется
его наличие в словаре и, ввиду отсутствия, записыва-
ется в словарь в позиции 3, формируя при этом выход-
ной код (0,7) .

3
4. Читается следующий символ 7 текста, проверяет-
ся его наличие в словаре. Поскольку символ 7 уже
имеется в словарь, производится считывание следую-
щего символа L текста и проверяется наличие в сло-
варе считаной двухсимвольной цепочки символов 7L .
Поскольку она там отсутствует, цепочка 7L заносится в
словарь под номером 4 и формируется выходной код
( 3, L) , где число 3 является меткой (номером) позиции в
словаре, в которой размещен префикс, т.е. в данном
случае первый символ 7 этой цепочки.
5. Вводится следующий символ Z выходного файла.
Он уже содержится в словаре в позиции 2. Поэтому
считывается очередной символ 7 . Двухсимвольная це-
почка Z7 в словаре отсутствует, поэтому она туда за-
носится под номером 5 и формируется выходной код
( 2,7) .
6. Считывается очередной символ 7 текста. Прове-
ряется, что он уже находится в словаре под номером 3.
Поэтому считывается следующий символ ” . “ и прове-
ряется наличие в словаре цепочки символов “ 7 ”. Ввиду
ее отсутствия в словаре она вносится в него в позиции
6 и формируется выходной код ( 3, '.' ) .
Таким образом, кодированный файл представляет
собой последовательность кодов: (0,1) (0, Z) (0,7) ( 3, L)
( 2,7) ( 3, '.' ) . Так как размер словаря не превышает 8 би-
тов, то для двоичного представления номера метки лю-
бой его позиции, т.е. первого элемента кодового слова
достаточно log2 8  3 бита. Если для представления
символа на втором поле кодового слова использовать
8 – битовый код ASCII, то длина одного кодового слова
составляет 3  8  11 бит, а общая длина кодированного
текста будет равна 11  6  66 бит. По сравнению с дли-
ной исходного некодированного файла в ASCII-
формате, равной 8  9  72 битам, имеет место сжатие
4
кодированного файла с коэффициентом:

K C  66  0.92 (92%).
72

б) Декодирование
1. При поступлении на вход декодера кодового слова
(0, L) , он выдает на выход символ L и записывает его в
словарь под номером 1.
2. При поступлении кода (0, Z) декодер выдает на
выход символ ( Z) и записывает его в словарь под но-
мером 2.
3. При подаче кода (0,7) декодер вырабатывает на
выходе символ 7 и заносит его в словарь под номером
3.
4. При поступлении кода ( 3L) декодер на метке 3
находит записанный на позиции 3 символ 7 , выдает на
выход двухсимвольную цепочку 7L и записывает ее в
свой словарь под номером 4.
5. При подаче следующего кода ( 2,7) декодер по
номеру метки 2 извлекает из своего словаря записан-
ный под этим номером символ (7) , выдает на выход
двухсимвольную цепочку ( Z7) и записывает ее в сло-
варь под номером 5.
6. В результате обработки последнего кодового сло-
ва 3, "." декодер находит в словаре записанный в по-
зиции 3 символ 7 , выдает на выход двухсимвольную
цепочку 7 и записывает ее в словарь. В итоге, декоди-
рованный текст имеет вид LZ 77LZ 77. , т.е. текст вос-
становлен правильно.
Результаты работы кодера и декодера представ-
лены в табл. 8.11.

5
Таблица 8.11. Результаты кодирования и
декодирования в примере 8.12

Кодирование

Вход Выход
Индекс
(словарь) (код)
- 0 -
L 1 (0,L)
Z 2 (0,Z)
7 3 (0,7)
7L 4 (3,L)
Z7 5 (2,7)
7. 6 (3,“•”)

Декодирование

Вход Выход и
Индекс
(код) словарь
- - 0
(0,L) L 1
(0,Z) Z 2
(0,7) 7 3
(3,L) 7L 4
(2,7) Z7 5
(3,”•“) 7. 6