Lempel–Ziv–Welch 字符串压缩算法
Last updated
Was this helpful?
Last updated
Was this helpful?
MIT 的 Information and Entropy 公开课讲的信息论与压缩,讲的非常 nice ! 唯一美中不足的地方是教授一步一步复现 LZW 算法的时候一开始搞错了。。卡住之后才发现出了 bug 修正过来,囧
LZW 算法的一个 pdf 课件。
简单看了两天笔记之后,总结了下,教材上常见的字符串压缩可以分为 Huffman encoding 和 LZ 系列 - LZ77, LZ78, LZW 等等。
Huffman Encoding:
建立在字符pattern的 “出现概率” 上,把出现概率大的pattern用更短的 encoding 方式表达出来,这样就可以节省原始字符串的期望长度。
Huffman Encoding 的结构是树状的,一种常见的 variable-length code (又称前缀树) 大概长这样:
其中 0 - B; 10 - A; 110 - C,以此类推。
Theorem 3.1 Huffman coding produces a code tree whose expected length is optimal, when restricted to symbol-by-symbol coding with symbols drawn in IID fashion from a known symbol probability distribution.
在 symbol 的 pdf 已知的情况下,Huffman Encoding 的期望长度是最优的。问题就出在这个 “symbol pdf 已知” 上,因为实际应用中很多时候得到 symbol 的 pdf 不但昂贵,也不擅于处理不同 message 之间,symbol 出现概率可能出现的大幅度变化。而且这种方法做了一个类似 naive bayes 的假设,就是 symbol 之间是 iid 关系,independent and identically distributed.
LZW 算法最有意思的一点是,在 stream of input/output 进行的过程中,双方不需要传递用于encode/decode 的 String table ,decoder 可以"猜"出来应该对应的是什么。 而且如果原始 table 已经满了的话,可以直接重新初始化,继续 streaming.
一段比较简单粗暴的代码,跑了几个 test case 结果无误,压缩效率尚可。LZW 因为 prefix 搜索非常多,可以用 Trie 进行优化。
里面一些细节因为时间有限先不赘述了,复习去。
实际应用中 key 的 size 最好小点,至少最好不要比一个 char 大(同时保证字典不会 overflow),下面的代码用的就是 8-bit byte 做字典 HashMap 与 TrieNode 的 key,有效范围在 0 ~ 255 之间。