Алгоритмы LZ77 и LZ78 — различия между версиями
Yulya3102 (обсуждение | вклад) |
Yulya3102 (обсуждение | вклад) (→LZ78) |
||
Строка 45: | Строка 45: | ||
== LZ78 == | == LZ78 == | ||
− | === Описание алгоритма === | + | === Описание алгоритма === |
− | + | Алгоритм LZ78 вносит все встреченные последовательности в словарь. Каждый раз, когда среди данных, которые нужно сжать, встречается последовательность, программа обращается к словарю: | |
− | === Пример | + | * если последовательность находится в словаре, то на выход подается код для этой записи |
+ | |||
+ | * если последовательность - дополненная версия последовательности из словаря, то эта последовательность добавляется в словарь | ||
+ | |||
+ | Например, если в словаре уже хранится последовательность ''ABC'', и программа встречает последовательность ''ABCA'', то на выход сначала подается код из словаря для ''ABC'', затем символ ''A'', а затем последовательность ''ABCA'' будет добавлена в словарь. Если потом встретится последовательность ''ABCAB'', на выход подастся код для ''ABCA'', символ ''B'', и в словарь добавится ''ABCAB''. Каждый раз, когда программа встречает последовательность из словаря, она выдает код и добавляет в словарь новую последовательность, которая на один байт длиннее. | ||
+ | === Пример === | ||
{| border="1" | {| border="1" | ||
− | ! | + | !Сообщение |
− | ! | + | !Код |
− | ! | + | !Новая последовательность в словаре |
|- | |- | ||
− | + | | <tex>\ abracadabra</tex> | |
− | |<tex> | ||
− | |||
− | |||
− | |||
− | |||
|<0,<tex>a</tex>> | |<0,<tex>a</tex>> | ||
+ | |<tex>1.\ a</tex> | ||
|- | |- | ||
− | | | + | |<tex>a\ bracadabra</tex> |
− | |||
|<0,<tex>b</tex>> | |<0,<tex>b</tex>> | ||
+ | |<tex>2.\ b</tex> | ||
|- | |- | ||
− | |<tex> | + | |<tex>ab\ racadabra</tex> |
− | |<tex> | + | |<0,<tex>r</tex>> |
− | | | + | |<tex>3.\ r</tex> |
|- | |- | ||
− | |<tex> | + | |<tex>abr\ acadabra</tex> |
− | |<tex> | + | |<1,<tex>c</tex>> |
− | + | |<tex>4.\ ac</tex> | |
|- | |- | ||
− | |<tex> | + | |<tex>abrac\ adabra</tex> |
− | + | |<1,<tex>d</tex>> | |
− | | | + | |<tex>5.\ ad</tex> |
|- | |- | ||
− | |<tex> | + | |<tex>abracad\ abra</tex> |
− | |<tex> | + | |<1,<tex>b</tex>> |
− | + | |<tex>6.\ ab</tex> | |
|- | |- | ||
− | |<tex> | + | |<tex>abracadab\ ra</tex> |
− | + | |<3,<tex>a</tex>> | |
− | | | + | |<tex>7.\ ra</tex> |
|} | |} | ||
Версия 22:08, 10 апреля 2012
LZ77 и LZ78 - алгоритмы сжатия без потерь, опубликованные в статьях Абрахама Лемпеля и Якоба Зива в 1977 и 1978 годах. Эти алгоритмы - самые известные варианты в семье LZ*, которая также включает LZW, LZSS, LZMA и другие алгоритмы. Оба алгоритма - алгоритмы со словарным подходом. Алгоритм LZ77 использует "скользящее окно", которое эквивалентно неявному использованию словарного подхода, сначала предложенного в LZ78.
Содержание
LZ77
Описание алгоритма
LZ77 использует уже просмотренную часть сообщения как словарь. Чтобы достигнуть сжатия, алгоритм пытается заменить очередной фрагмент сообщения на указатель в содержимое словаря.
В качестве модели данных LZ77 использует "скользящее" по сообщению окно, разделенное на две неравных части. Первая часть, большая по размеру, включает уже просмотренную часть сообщения. Вторая, намного меньшая, - буфер, содержащий еще не закодированные символы. Как правило, размер окна - несколько килобайтов. Буфер намного меньше, обычно не больше, чем сто байтов. Алгоритм пытается найти фрагмент в словаре, который совпадает с содержанием буфера.
Алгоритм LZ77 выдает коды, состоящие из трех элементов:
- смещение в словаре относительно его начала подстроки, которая соответствует содержанию буфера;
- длина подстроки;
- первый символ в буфере после подстроки.
После этого алгоритм перемещает окно на длину совпадающей подстроки +1 символ влево.
Если совпадение не найдено, алгоритм выдает код <0, 0, первый символ в буфере> и продолжает свою работу. Хотя такое решение неэффективно, оно гарантирует, что алгоритм сможет закодировать любое сообщение.
Пример
Сообщение | Подстрока | Код |
---|---|---|
<0,0, | >||
<0,0, | >||
<0,0, | >||
<2,2, | >||
<2,5, | >
LZ78
Описание алгоритма
Алгоритм LZ78 вносит все встреченные последовательности в словарь. Каждый раз, когда среди данных, которые нужно сжать, встречается последовательность, программа обращается к словарю:
- если последовательность находится в словаре, то на выход подается код для этой записи
- если последовательность - дополненная версия последовательности из словаря, то эта последовательность добавляется в словарь
Например, если в словаре уже хранится последовательность ABC, и программа встречает последовательность ABCA, то на выход сначала подается код из словаря для ABC, затем символ A, а затем последовательность ABCA будет добавлена в словарь. Если потом встретится последовательность ABCAB, на выход подастся код для ABCA, символ B, и в словарь добавится ABCAB. Каждый раз, когда программа встречает последовательность из словаря, она выдает код и добавляет в словарь новую последовательность, которая на один байт длиннее.
Пример
Сообщение | Код | Новая последовательность в словаре |
---|---|---|
<0, | >||
<0, | >||
<0, | >||
<1, | >||
<1, | >||
<1, | >||
<3, | >