4.2 Кодирование словарей, алгоритм Зива
Алгоритм Лемпеля-Зива-Велча - это универсальный алгоритм сжатия данных без потерь, созданный Абрахамом Лемпелем, Якобом Зивом и Терри Велчем. Он был опубликован Велчем в 1984 году, в качестве улучшенной реализации алгоритма LZ78, опубликованного Лемпелем и Зивом в 1978 году. Алгоритм разработан так, чтобы его можно было быстро реализовать, но он не обязательно оптимален, поскольку он не проводит никакого анализа входных данных.
Акроним "LZW" указывает на фамилии изобретателей алгоритма: Лемпель, Зив и Велч, но многие утверждают, что, поскольку патент принадлежал Зиву, то метод должен называться алгоритмом Зива-Лемпеля-Велча.
Данный алгоритм при сжатии (кодировании) динамически создаёт таблицу преобразования строк: определённым последовательностям символов (словам) ставятся в соответствие группы бит фиксированной длины (обычно 12-битные). Таблица инициализируется всеми 1-символьными строками (в случае 8-битных символов - это 256 записей). По мере кодирования, алгоритм просматривает текст символ за символом, и сохраняет каждую новую, уникальную 2-символьную строку в таблицу в виде пары код/символ, где код ссылается на соответствующий первый символ. После того как новая 2-символьная строка сохранена в таблице, на выход передаётся код первого символа. Когда на входе читается очередной символ, для него по таблице находится уже встречавшаяся строка максимальной длины, после чего в таблице сохраняется код этой строки со следующим символом на входе; на выход выдаётся код этой строки, а следующий символ используется в качестве начала следующей строки.
Алгоритму декодирования на входе требуется только закодированный текст, поскольку он может воссоздать соответствующую таблицу преобразования непосредственно по закодированному тексту.
Алгоритм:
1. Инициализация словаря всеми возможными односимвольными фразами. Инициализация входной фразы w первым символом сообщения.
2. Считать очередной символ K из кодируемого сообщения.
3. Если КОНЕЦ_СООБЩЕНИЯ, то выдать код для w, иначе
4. Если фраза wK уже есть в словаре, присвоить входной фразе значение wK и перейти к Шагу 2, иначе выдать код w, добавить wK в словарь, присвоить входной фразе значение K и перейти к Шагу 2.
Конец
На момент своего появления алгоритм LZW давал лучший коэффициент сжатия, для большинства приложений, чем любой другой хорошо известный метод того времени. Он стал первым широко используемым на компьютерах методом сжатия данных.
Алгоритм был реализован в программе compress, которая стала более или менее стандартной утилитой Unix-систем приблизительно в 1986 году. Несколько других популярных утилит-архиваторов также используют этот метод или близкие к нему.
В 1987 году алгоритм стал частью стандарта на формат изображений GIF. Он также может (опционально) использоваться в формате TIFF.
В настоящее время, алгоритм содержится в стандарте PDF.
Кодирование
Без использования алгоритма LZW, при передаче сообщения как оно есть - 25 символов по 5 бит на каждый - оно займёт 125 бит. Сравним это с тем, что получается при использовании LZW:
Таким образом, используя LZW, мы сократили сообщение на 29 бит из 125 - это почти 22 %. Если сообщение будет длиннее, то элементы словаря будут представлять всё более и более длинные части текста, благодаря чему повторяющиеся слова будут представлены очень компактно.
Декодирование
Теперь представим, что мы получили закодированное сообщение, приведённое выше, и нам нужно его декодировать. Прежде всего, нам нужно знать начальный словарь, а последующие записи словаря мы можем реконструировать уже на ходу, поскольку они являются просто конкатенацией предыдущих записей.
Единственная небольшая трудность может возникнуть, если новое слово словаря пересылается немедленно. В приведённом выше примере декодирования, когда декодер встречает первый символ, T, он знает, что слово 27 начинается с T, но чем оно заканчивается? Проиллюстрируем проблему следующим примером. Мы декодируем сообщение ABABA:
На первый взгляд, для декодера это неразрешимая ситуация. Мы знаем наперёд, что словом 47 должно быть ABA, но как декодер узнает об этом? Заметим, что слово 47 состоит из слова 29 плюс символ идущий следующим. Таким образом, слово 47 заканчивается на "символ идущий следующим". Но, поскольку это слово посылается немедленно, то оно должно начинаться с "символа идущего следующим", и поэтому оно заканчивается тем же символом что и начинается, в данном случае - A. Этот трюк позволяет декодеру определить, что слово 47 это ABA.
В общем случае, такая ситуация появляется, когда кодируется последовательность вида cScSc, где c - это один символ, а S - строка, причём слово cS уже есть в словаре.
- Введение
- 1. Описание назначения всех команд меню WinRAR
- 2. Примеры создания и распаковывания архивов для текстовых, графических и системных файлов
- 2.1 Архивация файлов
- 2.2 Разархивация файлов
- 2.3 Примеры архивации и разархивации файлов
- 3. Примеры создания архивов с опциями: пароль, многотомный архив, самораспаковывающийся архив
- 3.1 Создание архива с опцией пароль
- 3.3 Создание многотомного архива
- 3.4 Создание самораспаковывающегося архива
- 4. Теоретические основы сжатия файлов
- 4.1 Кодирование числовых последовательностей
- 4.2 Кодирование словарей, алгоритм Зива
- Заключение