关键是抓住编码过程中当P+C不在字典里,才会输出P的过程。
LZW编码算法:
1. 初始状态,字典里只有所有的默认项,例如0->a,1->b,2->c。此时P和C都是空的。
2. 读入新的字符C,与P合并形成字符串P+C。
3. 在字典里查找P+C,如果:
- P+C在字典里,P=P+C。
- P+C不在字典里,将P的记号输出;在字典中为P+C建立一个记号映射;更新P=C。
4. 返回步骤2重复,直至读完原字符串中所有字符。
LZW解码算法:
1. 初始状态,字典里只有所有的默认项,例如0->a,1->b,2->c。此时pW和cW都是空的。
2. 读入第一个的符号cW,解码输出。注意第一个cW肯定是能直接解码的,而且一定是单个字符。
3. 赋值pW=cW。
4. 读入下一个符号cW。
5. 在字典里查找cW,如果:
a. cW在字典里:
(1) 解码cW,即输出 Str(cW)。
(2) 令P=Str(pW),C=Str(cW)的**第一个字符**。
(3) 在字典中为P+C添加新的记号映射。
b. cW不在字典里:
(1) 令P=Str(pW),C=Str(pW)的**第一个字符**。
(2) 在字典中为P+C添加新的记号映射,这个新的记号一定就是cW。
(3) 输出P+C。
6. 返回步骤3重复,直至读完所有记号。
步骤5.a中,由编码算法知,当P+C不在字典里时,会输出P,并在字典中添加一个映射P+C。
步骤5.b中,由于编码过程是先生成记号映射再继续编码,而解码过程是先知道编码结果再推导记号映射,故存在cW不在字典里的情况,因为该情况下,新的记号映射就为str(P)+str(cw)的第一个字符。