暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

LZW 压缩算法深入解析

原创 铁头娃学数据库 2025-10-11
346

一、算法背景与理论基础

1. 压缩的核心思想

LZW(Lempel–Ziv–Welch)算法是一种 无损数据压缩算法,由 Terry Welch 于 1984 年基于 LZ78 算法 改进提出。它的主要思想是:

用较短的编码(整数索引)替代重复出现的字符串模式,通过动态构建字典实现压缩。

与霍夫曼(Huffman)编码依赖统计频率不同,LZW 完全基于模式发现(pattern discovery),属于 基于词典(dictionary-based) 的压缩算法。


二、算法设计思想

LZW 的核心是“最长前缀匹配 + 自适应字典增长”。

1. 关键设计思想

  • 字典初始化:字典中预存所有基本符号(例如 ASCII 码 0–255)。
  • 最长匹配搜索:在当前输入流中找到最长的、已存在于字典中的字符串 w。
  • 输出编码:输出 w 对应的字典编码。
  • 扩展字典:将 w + c(c 为下一个新字符)加入字典。

这种机制确保字典逐步学习数据模式。


2. 压缩伪代码

Initialize dictionary with all single characters
w = ""                        // 当前匹配串
for each character c in input:
    if w + c in dictionary:
        w = w + c
    else:
        output code(w)
        add (w + c) to dictionary
        w = c
output code(w)


3. 解压伪代码

Initialize dictionary with all single characters
read first code k
output string(k)
w = string(k)
for each code k in remaining input:
    if k in dictionary:
        entry = string(k)
    else:
        entry = w + w[0]   // 处理未定义情况
    output entry
    add (w + entry[0]) to dictionary
    w = entry


三、压缩流程详解

TOBEORNOTTOBEORTOBEORNOT 这是 LZW 教材中经典的例子(因为它能充分展示字典的自适应增长过程)。 下面我们将从初始化字典 → 逐步压缩 → 输出编码 → 字典扩展全面展开。

一、实验环境与规则设定 字母表采用标准 ASCII(0–255)

为了便于展示,我们仅展示涉及到的字符及其对应字典索引 (初始字典中每个 ASCII 字符对应它的 ASCII 值)

每新增的字符串项从编码 256 开始编号

二、输入字符串:T O B E O R N O T T O B E O R T O B E O R N O T 

三、初始字典

编号 符号 说明
84 T ASCII
79 O ASCII
66 B ASCII
69 E ASCII
82 R ASCII
78 N ASCII
… … 其余 ASCII 字符略
256 起 新词条 LZW 运行时新增

🧠 四、压缩过程详解(逐步匹配) 我们从头扫描字符串,每次找“最长匹配的字符串 w”,输出其编码,并将“w + 下一个字符”加入字典。

步骤 当前串 (w+c) w 是否存在 输出编码 新增字典项 新编号
1 T ✔ - - -
2 TO ❌ 输出 T(84) 加入 TO 256
3 O ✔ - - -
4 OB ❌ 输出 O(79) 加入 OB 257
5 B ✔ - - -
6 BE ❌ 输出 B(66) 加入 BE 258
7 E ✔ - - -
8 EO ❌ 输出 E(69) 加入 EO 259
9 O ✔ - - -
10 OR ❌ 输出 O(79) 加入 OR 260
11 R ✔ - - -
12 RN ❌ 输出 R(82) 加入 RN 261
13 N ✔ - - -
14 NO ❌ 输出 N(78) 加入 NO 262
15 O ✔ - - -
16 OT ❌ 输出 O(79) 加入 OT 263
17 T ✔ - - -
18 TT ❌ 输出 T(84) 加入 TT 264
19 T ✔ - - -
20 TO ✔(256 已存在) 继续扩展 - -
21 TOB ❌ 输出 TO(256) 加入 TOB 265
22 B ✔ - - -
23 BE ✔(258 已存在) 继续扩展 - -
24 BEO ❌ 输出 BE(258) 加入 BEO 266
25 O ✔ - - -
26 OR ✔(260 已存在) 继续扩展 - -
27 ORT ❌ 输出 OR(260) 加入 ORT 267
28 T ✔ - - -
29 TO ✔(256 已存在) 继续扩展 - -
30 TOB ✔(265 已存在) 继续扩展 - -
31 TOBE ❌ 输出 TOB(265) 加入 TOBE 268
32 E ✔ - - -
33 EO ✔(259 已存在) 继续扩展 - -
34 EOR ❌ 输出 EO(259) 加入 EOR 269
35 R ✔ - - -
36 RN ✔(261 已存在) 继续扩展 - -
37 RNO ❌ 输出 RN(261) 加入 RNO 270
38 O ✔ - - -
39 OT ✔(263 已存在) 继续扩展 - -
40 OT(END) ❌ 输出 OT(263) 加入 OT? 271

📦 五、输出编码序列 根据上表输出: 84, 79, 66, 69, 79, 82, 78, 79, 84, 256, 258, 260, 265, 259, 261, 263 也就是: T, O, B, E, O, R, N, O, T, TO, BE, OR, TOB, EO, RN, OT


四、解压流程详解

由于字典是动态的,解码端必须与压缩端同步构建相同字典。

关键问题:

  • 解压时可能遇到**“字典中还未出现的编码”**;
  • 这发生在某个字典项刚被添加但编码尚未输出之前。

解决方案:

当遇到未知编码 k 时,用 w + w[0] 作为解码结果。

示例:

已知 w = AB
当前编码 k = 8(未定义)
推测 entry = w + w[0] = AB + A = ABA

五、现实应用与影响力

LZW 在实际工业与标准中影响深远。

它被应用在多个领域与协议中:

应用场景 格式 / 协议 说明
图像文件 GIF、TIFF 采用 LZW 作为核心压缩算法
文件压缩 Unix compress 命令 LZW 是早期 Unix 系统默认压缩
打印与文档 PostScript, PDF 内置 LZW 解码器,用于流式数据压缩
嵌入式通信 调制解调器 / 网络协议 低计算开销的实时压缩
存档与传输系统 ARC、PKZIP(早期版本) 后来演变为 DEFLATE(LZ77+Huffman)
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论