結論先行:LZ77 是一種類基于滑动窗口的字典圧縮アルゴリズム,核心思想是"用历史データ做字典,遇到重复コンテンツである引用回去"。エンコード时输出三元グループ (distance, length, next_char):回溯 distance つ字符找到匹配,匹配长度 length,紧跟一つ未匹配字符 next_char。以"abracadabra"この 11 つ字符である例,LZ77 エンコード后仅需 5 つ三元グループ即可表示,圧縮効果显著。LZ77 是 DEFLATE(ZIP/GZIP/PNG)的核心グループ件,也是 LZSS/LZMA/LZ4 等现代圧縮アルゴリズム的共同祖先。以下では滑动窗口原理から説明し,逐步演示エンコードプロセス。
もし Huffman エンコード的原理まだ慣れていない場合は,まずHuffman エンコード原理:圧縮アルゴリズム的基石詳解。
一、什么是字典圧縮
圧縮アルゴリズム分2大流派:統計エンコード(如 Huffman エンコード)按字符频率分配变长码字;字典圧縮用"指针引用"替换重复コンテンツ。LZ77 属于字典圧縮流派,它不预先构建字典表,而是用已処理的历史データ作である隐式字典——遇到重复コンテンツ时,用一つ"回溯指针"指向之前出现过的位置。
| 圧縮流派 | 核心原理 | 代表アルゴリズム | 优势 | 劣势 |
|---|---|---|---|---|
| 統計エンコード | 按频率分配变长码 | Huffman, 算术エンコード | 逼近熵下界 | 不擅长长程重复 |
| 字典圧縮 | 用引用替换重复コンテンツ | LZ77, LZW, LZMA | 擅长重复模式 | に対して随机データ无效 |
| 混合エンコード | 字典+統計2阶段 | DEFLATE, ZSTD | 综合最优 | 実現较複雑 |
| 变换エンコード | 变换到频域再量化 | DCT(JPEG), DWT | 有损圧縮効率高 | 有信息損失 |
实践中最流行的圧縮アルゴリズム几乎都是"混合エンコード"——先用 LZ77 消除重复模式,再用 Huffman に対して残差做频率圧縮。DEFLATE である是 LZ77 + Huffman 的经典グループ合,被 ZIP、GZIP、PNG 广泛使用。
二、LZ77 アルゴリズム原理詳解
LZ77 的核心是滑动窗口机制。窗口分である2部分:搜索缓冲区(已処理的历史データ)和前视缓冲区(待処理的未来データ)。エンコード时在前视缓冲区取一段コンテンツ,在搜索缓冲区中查找最长匹配,找到である输出三元グループ,找不到である输出元字符。
1. 滑动窗口構造
滑动窗口的大小直接决定圧縮効果——窗口越大,能回溯查找的历史データ越多,匹配概率越高。不同アルゴリズム的窗口大小差异很大。
| アルゴリズム | 搜索缓冲区 | 前视缓冲区 | 最大匹配长度 | 典型シナリオ |
|---|---|---|---|---|
| LZ77元 | 几KB | 十几字节 | 16字节 | 教学例 |
| DEFLATE | 32KB | 258字节 | 258字节 | ZIP/GZIP/PNG |
| LZMA | 8MB(可配) | 273字节 | 273字节 | 7z/xzアーカイブ |
| LZ4 | 64KB | 无制限 | 无制限 | 实时圧縮 |
| ZSTD | 8MB(最大1GB) | 无制限 | 无制限 | 现代通用 |
2. 三元グループエンコード形式
LZ77 的输出单元是三元グループ (distance, length, next_char),三つ字段的含义如下表。
| 字段 | 含义 | 取值範囲(DEFLATE) | エンコード位数 | 例 |
|---|---|---|---|---|
| distance | 回溯距离(向后多少字符找匹配) | 1–32768 | 15 bit | distance=10 → 往前10つ字符 |
| length | 匹配长度(连续匹配多少字符) | 3–258 | 8 bit | length=5 → 匹配5つ字符 |
| next_char | 匹配后的下一つ字符 | 0–255 | 8 bit | next_char='d' → ASCII 100 |
三元グループ的巧妙之处在于:匹配结束后多输出一つ next_char,保证エンコーダー总能向前推进至少 1 つ字符,不会卡死。如果找不到任何匹配(length=0),distance 和 length 都である 0,只输出 next_char——相当于退化である元字符ストレージ。
3. 匹配查找戦略
匹配查找是 LZ77 的性能瓶颈——在前视缓冲区取一段コンテンツ,在搜索缓冲区中找最长匹配。暴力查找是 O(n×m) 複雑度,实际実現用哈希表或后缀树加速。
| 查找戦略 | データ構造 | 查找複雑度 | 空間开销 | 典型適用 |
|---|---|---|---|---|
| 暴力查找 | 无 | O(n×m) | 无 | 教学例 |
| 哈希链 | 哈希表+链表 | O(n)平均 | 低 | zlib(DEFLATE) |
| 哈希桶 | 哈希表+数グループ | O(1)平均 | 中 | LZ4 |
| 后缀树 | 后缀树/后缀数グループ | O(n)最坏 | 高 | LZMA |
三、実戦案例:"abracadabra"エンコード演示
用 LZ77 に対して"abracadabra"(11 つ字符)行う完整エンコード。初始状态搜索缓冲区である空,前视缓冲区である整つ字符串。逐つ位置扫描,在历史データ中查找最长匹配。
原文: a b r a c a d a b r a
エンコードプロセス:
| ステップ | 当前位置 | 前视コンテンツ | 搜索缓冲区查找 | 输出三元グループ | 説明 |
|---|---|---|---|---|---|
| 1 | 位置1 | abracadabra | 空,无匹配 | (0, 0, 'a') | 首つ字符,直接输出 |
| 2 | 位置2 | bracadabra | "a",无匹配"b" | (0, 0, 'b') | 首次出现,直接输出 |
| 3 | 位置3 | racadabra | "ab",无匹配"r" | (0, 0, 'r') | 首次出现,直接输出 |
| 4 | 位置4 | acadabra | "abr"中找到"a" | (0, 0, 'a') | "a"出现但后续不匹配 |
| 5 | 位置5 | cadabra | "abra"中无"c" | (0, 0, 'c') | 首次出现,直接输出 |
| 6 | 位置6 | adabra | "abrac"中找到"a" | (0, 0, 'a') | "a"匹配但后续不匹配 |
| 7 | 位置7 | dabra | "abraca"中无"d" | (0, 0, 'd') | 首次出现,直接输出 |
| 8 | 位置8 | abra | 回溯7找到"abra"匹配 | (7, 4, end) | 匹配"abra"4つ字符 |
エンコード効率比較:
| エンコード方式 | 输出单元数 | 每单元bit | 总bit | vs元节省 |
|---|---|---|---|---|
| ASCII元 | 11字符 | 8 | 88 | —(基准) |
| LZ77(无匹配最適化) | 8三元グループ | 31(平均) | 248 | -182%(膨胀) |
| LZ77(最適化标记位) | 8单元 | 12(平均) | 96 | -9%(略膨胀) |
| LZ77+Huffman | 8单元 | 4.5(平均) | 36 | 59% |
結果分析: 纯 LZ77 に対して短字符串可能膨胀(三元グループ比元字符占用更多空間),このである是である什么 LZ77 通常与 Huffman エンコードグループ合使用——DEFLATE である是 LZ77 + Huffman。在"abracadabra"案例中,位置 8 的匹配"abra"(distance=7, length=4)是重要圧縮点,4 つ字符用一つ三元グループ表示。に対して于更长、重复模式更多的文本(如コードファイル、日志),LZ77 的圧縮効果会显著向上。
四、LZ77 变体与现代演化
LZ77 自 1977 年提出后衍生出大量变体,每つ变体针に対して特定シナリオ最適化了某つ维度。下表比較主流 LZ77 家族成员。
| アルゴリズム | 重要改进 | 圧縮率 | 圧縮速度 | 解压速度 | 典型適用 |
|---|---|---|---|---|---|
| LZ77(元) | 三元グループエンコード | 低 | 慢 | 中 | 教学 |
| LZSS | 用标记位区分匹配/字面量 | 中 | 中 | 快 | 早期システム |
| DEFLATE | LZSS+Huffman2阶段 | 中高 | 中 | 快 | ZIP/GZIP/PNG |
| LZMA | 大窗口+区間エンコード+最优解析 | 高 | 慢 | 中 | 7z/xzアーカイブ |
| LZ4 | 牺牲圧縮率换极致速度 | 低 | 极快 | 极快(4GB/s) | 实时/内核 |
| LZW | 显式字典表(非滑动窗口) | 中 | 快 | 快 | GIF/TIFF |
| ZSTD | LZ77变体+FSE+字典预设 | 高 | 快 | 极快 | 现代通用 |
から演化趋势看,现代アルゴリズム(ZSTD、brotli)在保持高圧縮率的同时大幅向上了速度,逐渐取代 DEFLATE 成である新一代標準。但 LZ77 的核心思想——滑动窗口字典引用——始终未变,所有变体都建立在このつ基础之上。
| シナリオ | 推奨アルゴリズム | 理由 | 圧縮率参照 |
|---|---|---|---|
| ファイルアーカイブ | LZMA(xz) | 圧縮率最高,不追求速度 | 70%–85% |
| 通用圧縮 | ZSTD | 圧縮率和速度兼顾 | 60%–80% |
| 实时転送 | LZ4 | 解压速度4GB/s,延迟极低 | 50%–65% |
| Web転送 | DEFLATE/GZIP | 互換性最好,所有浏览器サポート | 50%–70% |
| 画像形式 | DEFLATE(PNG) | 无损圧縮,適した图形类 | 50%–75% |
| 内存データ | LZ4 | 低CPU占用,適した高频圧縮 | 50%–65% |
について PNG 形式中 DEFLATE 的具体適用,を参照してくださいPNG 圧縮原理詳解。无损圧縮与有损圧縮的区别,を参照してください无损圧縮 vs 有损圧縮:核心区别。
五、よくある質問FAQ
Q1:LZ77アルゴリズム是什么?
LZ77 是一種類基于滑动窗口的字典圧縮アルゴリズム,由 Lempel 和 Ziv 于 1977 年提出。核心思想是:用之前已処理的データ作である字典,遇到重复コンテンツ时用 (distance, length, next_char) 三元グループ替换元データ,distance 表示回溯距离,length 表示匹配长度,next_char 表示匹配后的下一つ字符。LZ77 是 DEFLATE(ZIP/GZIP/PNG) 的核心グループ件,也是 LZSS/LZMA/LZ4 等现代アルゴリズム的祖先。
Q2:LZ77的滑动窗口是什么意思?
滑动窗口是 LZ77 的核心データ構造,分である搜索缓冲区(已処理的历史データ)和前视缓冲区(待処理的未来データ)。エンコード时在前视缓冲区中取一段コンテンツ,在搜索缓冲区中查找最长匹配。典型窗口大小である 32KB(DEFLATE 標準),窗口越大匹配概率越高但内存开销越大。窗口大小决定了最大回溯距离 distance 的上限。
Q3:LZ77和LZ78有什么区别?
LZ77 用滑动窗口做隐式字典,匹配コンテンツ直接引用历史データ,不单独ストレージ字典;LZ78 用显式字典表,を已见的字符串编号ストレージである字典条目,エンコード时输出字典索引。LZ77 更適した有局部重复的データ(如文本),LZ78 更適した全局重复的データ。实践中 LZ77 的后代(DEFLATE/LZMA/LZ4)远比 LZ78 的后代(LZW)更流行。
Q4:LZ77、LZMA、LZ4哪つ圧縮率最高?
圧縮率排序:LZMA > LZ77(DEFLATE) > LZ4。LZMA 用更大的窗口(デフォルト 8MB)、更优的匹配アルゴリズム和区間エンコード,圧縮率最高但速度最慢;DEFLATE 窗口 32KB + Huffman,圧縮率中等速度中等;LZ4 牺牲圧縮率换取极致速度,圧縮率最低但解压速度可达 4GB/s。选型取决于シナリオ:アーカイブ选 LZMA,通用选 DEFLATE/ZSTD,实时选 LZ4。
まとめ
LZ77 是字典圧縮アルゴリズム的鼻祖,核心原理是"滑动窗口 + 三元グループ引用":用历史データ做隐式字典,遇到重复コンテンツである输出 (distance, length, next_char) 三元グループ。纯 LZ77 に対して短文本可能膨胀,但与 Huffman エンコードグループ合后(DEFLATE)成である ZIP/GZIP/PNG 的標準圧縮ソリューション。现代变体 LZMA 追求极致圧縮率,LZ4 追求极致速度,ZSTD 兼顾2者。
理解 LZ77 的重要三点:一是滑动窗口决定匹配範囲(DEFLATE 32KB,LZMA 8MB),二是三元グループ是基本エンコード单元(回溯+长度+下一字符),三是匹配查找戦略决定性能(哈希链最快,后缀树最优)。LZ77 + Huffman 的混合エンコード是现代无损圧縮的黄金標準。
ファイルを圧縮してみませんか?SmartSlimを試す
独自開発のRust圧縮エンジンに基づき、PDF/画像/動画/Office/OFDなど10分野40以上の形式に対応。ローカル圧縮でデータは外部に送信されません。