LZ78-ウィキペディア、無料百科事典
LZ78 – 安定したデータ圧縮の辞書方法。 1978年にJa’akówZiwaとAwraham Lempelによって開発され、 情報理論に関するIEEEトランザクション 、w artykule pt。 「可変レートエンコーディングを介した個々の配列の圧縮」(s。530–536)。
圧縮は、シンボルの文字列を、以前に圧縮データに表示されていたシンボルの文字列を保存する辞書のインデックスに置き換えることです。これのおかげで、シンボルの繰り返しの文字列(たとえば、テキスト内の同じ単語またはフレーズ)は、はるかに短いインデックス(数字)に置き換えられます。
1年前のLZ78の著者は、辞書が永続的であるLZ77メソッドを開発し、その結果、新しいデータの流れでそのコンテンツが常に変化しました。その結果、彼が以前に演奏していた入り口で弦が繰り返されたが、彼は辞書にこれ以上いなかった場合、彼は再び記憶されなければなりませんでした。
一般に、LZ78メソッドはLZ77に非常に似ていますが、辞書が外部であり、必要に応じて拡張されていることを除いて、処理されたデータの文字列は失われません。これにより、個々の単語へのアクセス速度により、辞書への複雑なアクセスを犠牲にして、より良い圧縮係数が取得されます。ツリー(バイナリ、トリ)またはハッシュとして実装されます。
この方法の大きな利点は、一般的に潜在的に非常に大きな辞書が 覚えておく必要はありません – コード化されたデータに基づいてデコーダーによって再現されます(減圧の例を参照)。ただし、不利な点は、コードと減圧の実質的に同じ複雑さです。
実際には、LZWと呼ばれるLZ78バリアントが広く使用されています。
文字列が圧縮されています
含む
シンボル。
- 辞書をクリアします。
- ( – 最初の、未処理のシンボルのインデックス )。
- に限って 実行:
- 辞書で検索してください最長のBeachaは未加工のシンボルの始まりに等しい(排水 )。
- そのようなプルを見つけた場合、検索の結果はそのインデックスです 辞書;さらに、このインデックスで示される単語は確かです 終了するには、ペア(インデックス、最初の不一致のシンボル)を書きます。 )そして辞書に追加して、シンボルに拡張された微妙なものが見つかりました (言い換えれば、プル )。増加
- ドラフトを見つけられなかった場合、それは辞書にまだシンボルがないことを意味します 次に、この記号が辞書に追加され、蒸気が書き出されます( )。ここでは、インデックス0は従来型ですが、一般的な場合は、識別された数字についてです。増加 o 1つ。
- 辞書で検索してください最長のBeachaは未加工のシンボルの始まりに等しい(排水 )。
ただし、実際のプロジェクトでは、辞書にはあります 限られたサイズ – コーダー(およびデコーダー)は、辞書がオーバーフローしているという事実に異なって反応します。辞書は次のことができます:
- ゼロ;
- 新しい単語の追加が停止されています。
- 最も早く追加された単語。
- 最も頻繁に発生する単語は削除されます。
ユニバーサルコンプレスプログラムでは、追加の単語が吊り下げられていますが、圧縮係数が特定のレベルを下回ると、辞書はゼロになります。
- 辞書をクリアします。
- すべてのカップル(インデックス、シンボル – ) 実行:
- もしも シンボルを追加します 辞書に。シンボルを出口に書き込みます
- もしも インデックスの下から 出口に単語を書きます そしてシンボル 次のインデックスの下にある辞書に単語を追加します
LZ78メソッドは長年にわたって改善されてきました。これは、最も重要な変更のリストです。
- LZW(Terry Welch、1984)、LZC(1985) – LZWの実用的な実装
- LZJ (Matti Jakobson、1985)
- LZT (J. Tischer、1987)、LZW修正
- LZMW(1985)、LZAP(1988)-LZW修正
文字列は圧縮されます: abbbeabcbyaaaaac 。
エントリ | 出口 | 辞書 | コメント | |
---|---|---|---|---|
索引 | 言葉 | |||
a | (0、 a )) | 初め | a | 辞書にはシンボルはありません a |
b | (0、 b )) | 2 | b | 辞書にはシンボルはありません b |
BB | (2、 b )) | 3 | BB | 辞書に文字列があります b (インデックス2)ただし、 BB ;ペアは出口(既存の単語、シンボル)に保存され、辞書に新しい単語が追加されます BB |
c | (0、 c )) | 4 | c | 辞書にはシンボルはありません c |
aa | (初め、 a )) | 5 | aa | 辞書に文字列があります a (インデックス1)ただし、 aa ;ペアは出口(既存の単語、シンボル)に保存され、辞書に新しい単語が追加されます aa |
BBC | (3、 c )) | 6 | BBC | 辞書に文字列があります BB (インデックス3)ただし、 BBC ;ペアは出口(既存の単語、シンボル)に保存され、辞書に新しい単語が追加されます BBC |
BBCA | (6、 a )) | 7 | BBCA | 辞書に文字列があります BBC (インデックス6)しかし、 BBCA ;ペアは出口(既存の単語、シンボル)に保存され、辞書に新しい単語が追加されます BBCA |
AAC | (5、 c )) | 8 | AAC | 辞書に文字列があります aa (インデックス5)しかし、 AAC ;ペアは出口(既存の単語、シンボル)に保存され、辞書に新しい単語が追加されます AAC |
辞書に長い単語が追加されていることがわかります。
前の例からのデータは廃棄されます。
エントリ | 出口 | 辞書 | コメント | |
---|---|---|---|---|
索引 | 言葉 | |||
(0、 a )) | a | 初め | a | シンボル a 出口に導かれ、単一の要素文字列が辞書に追加されます a |
(0、 b )) | b | 2 | b | シンボル b 出口に導かれ、単一の要素文字列が辞書に追加されます b |
(2、 b )) | BB | 3 | BB | 終了に単語が書かれています b 辞書(インデックス2)から、シンボルも書き出されます b ;辞書に新しい継続が追加されます。これは、2つの単語とシンボルを接着しています。 BB |
(0、 c )) | c | 4 | c | シンボル c 出口に導かれ、単一の要素文字列が辞書に追加されます c |
(初め、 a )) | aa | 5 | aa | 終了に単語が書かれています a 辞書(インデックス1)から、シンボルも書き出されます a ;新しい継続が辞書に追加されます。辞書は、1という言葉を接着しています。 aa |
(3、 c )) | BBC | 6 | BBC | 終了に単語が書かれています BB 辞書(インデックス3)から、シンボルも書き出されます c ;辞書に新しい継続が追加されます。これは、2つの単語とシンボルを接着しています。 BBC |
(6、 a )) | BBCA | 7 | BBCA | 終了に単語が書かれています BBC 辞書(インデックス6)から、シンボルも書き出されます a ;単語6とシンボルの新しい継続が辞書に追加されます。 BBCA |
(5、 c )) | AAC | 8 | AAC | 終了に単語が書かれています aa 辞書(インデックス5)から、シンボルも書き出されます c ;辞書に新しい継続が追加されます。これは、5つの単語とシンボルの接着です。 AAC |
LZ78メソッドを使用してPythonコードで書かれた以下のプログラム( LZ78_ENCODE )そして、脱化する( LZ78_DECODE )そして最後に、コーディングとデコードのプロセスが正しく進んだかどうかを述べ、要約を表示します。
Pythonの記事のソースが圧縮されたときのプログラムの結果の例:
$ python lz78.py python-artykul.txt ペア数:6295 コードを保存するために必要な最大数:13 最大ペアを保存するために必要なビット数:13 + 8 = 21 入力データサイズ:23805バイト 圧縮データのサイズ:16525バイト 圧縮度:30.58%
注意: 圧縮の程度は、コードを記録する方法にも依存します – 圧縮データと圧縮のサイズを計算するこのプログラムでは、各コードに一定のビット数があると想定されています。実際のアプリケーションでは、ソリューションが異なる場合があります。
# - * - コーディング:ISO-8859-2-* - def LZ78_ENCODE ( データ ): d = {} n = 初め c = '' 結果 = [] ために s の データ : もしも c + s いいえ の d : もしも c == '' : #特別ケース:シンボル「S」 #は辞書にまだ表示されていません 結果 。 追加 ( ( 0 、 s )) )) d [ s ] = n それ以外 : #Stret 'C'は辞書にあります 結果 。 追加 ( ( d [ c ]、、 s )) )) d [ c + s ] = n n = n + 初め c = '' それ以外 : c = c + s 戻る 結果 def LZ78_DECODE ( データ ): d = {} n = 初め 結果 = [] ために 私 、 s の データ : もしも 私 == 0 : 結果 。 追加 ( s )) d [ n ] = s n = n + 初め それ以外 : 結果 。 追加 ( d [ 私 ] + s )) d [ n ] = d [ 私 ] + s n = n + 初め 戻る '' 。 加入 ( 結果 )) もしも __名前__ == '__主要__' : 輸入 sys から 算数 輸入 ログ 、 天井 もしも それだけ ( sys 。 argv )) < 2 : 印刷 「ファイル名を入力」 sys 。 出口 ( 初め )) データ = 開ける ( sys 。 argv [ 初め ])) 。 読む () comp = LZ78_ENCODE ( データ )) 分解 = LZ78_DECODE ( comp )) もしも データ == 分解 : k = それだけ ( comp )) n = int ( 天井 ( ログ ( マックス ( 索引 ために 索引 、 シンボル の comp )、、 2.0 )))) L1 = それだけ ( データ )) L2 = ( k * ( n + 8 )) + 7 )) / 8 印刷 「カップルの数: %d 「 % k 印刷 「マックス。コードを保存するために必要なビット数: %d 「 % n 印刷 「マックス。ペアを保存するために必要なビット数: %d + %d = %d 「 % ( n 、 8 、 n + 8 )) 印刷 「入力データサイズ: %d バイト」 % L1 印刷 「圧縮データのサイズ: %d バイト」 % L2 印刷 「圧縮度: %2F %% 「 % ( 100.0 * ( L1 - L2 )) / L1 )) #データを印刷します #decompを印刷します それ以外 : 印刷 「間違いがありました!」
- Adam Drozdek: データ圧縮の紹介 。ワルシャワ:wydawnictwo naukowo-techniczne、1999。ISBN 83-204-2303-1 。
Recent Comments