LZW 压缩/解压算法
lzw算法是基于"字节"(这里的字节流并不一定是8bit的,算法对这个没有要求,通常为了处理方便会把这个设为8)流编码的压缩算法,它的主要思想是对整个字符序列片断进行编码,并通过(前序 + 码表)的方式产生字符序列。 lzw最大的优点是它的码表是动态产生的,只要加压表和解压表的状态一致,就能解压。算法描述:
压缩
STRING = get input character
WHILE there are still input characters DO
CHARACTER = get input character
IF STRING+CHARACTER is in the string table then
STRING = STRING+character
ELSE
output the code for STRING
add STRING+CHARACTER to the string table
STRING = CHARACTER
END of IF
END of WHILE
output the code for STRING
解压缩
Read OLD_CODE
output OLD_CODE
CHARACTER = OLD_CODE
WHILE there are still input characters DO
Read NEW_CODE
IF NEW_CODE is not in the translation table THEN
STRING = get translation of OLD_CODE
STRING = CHARACTER + STRING
ELSE
STRING = get translation of NEW_CODE
END of IF
output STRING
CHARACTER = last character in STRING
add OLD_CODE + CHARACTER to the translation table
OLD_CODE = NEW_CODE
END of WHILE (对于不同的实现:“ STRING = CHARACTER + STRING” 和“CHARACTER = last character in STRING ”,可能需要修改为:“ STRING = STRING + CHARACTER" 和 “CHARACTER = first character in STRING ").
压缩流程:
设置处理的码字位数(其实是计算)
根据数据中可能存在的符号进行编码,
假设一共有4个符号: A B C D
那么对符号进行编码: 00 01 10 11
这样码字位数就是2,同时为了表示结束码,那么有效的码字位数至少需要2+1 = 3
|
计算传输码字的位数(其实是选择,它的长度>=有效码字的位数)
|
根据上面的算法,跟踪一下编码的流程看看(设传输码字的位数为3)
对于输入序列进行编码: AABCABCAB
|-------|--------|--------|-------------|-------|------| |--------|-------|---------|------------|------------|
|输入 |前序 |组合 |组合编码 |输出 |码字|=>|接收 |前序 |组合 |组合编码 |解压输出|
|-------|--------|--------|-------------|-------|------| |--------|-------|---------|------------|------------|
| A | -- | -- | -- |-- |-- | | -- | -- | -- | -- |-- |
| A | A | AA | 4 |A |000 | | 000 | -- | -- | -- |-- |
| B | A | AB | 5 |A |000 | | 000 | A | AA | 4 | A |
| C | B | BC | 6 |B |001 | | 001 | A | AB | 5 | A |
| A | C | CA | 7 |C |010 | | 010 | B | BC | 6 | B |
| B | A | AB | 5 |-- |-- | |-- | -- | -- | -- | -- |
| C | 8 | 5C | 8 |5 |101 | | 101 | C | C5 | 7 | C |
| A | C | CA | 7 |-- |-- | |-- | -- | -- | -- | -- |
| B | 7 | 7B | 9 |7 |111 | | 111 | 5 | 57 | 8 | AB |
| END| B | -- | -- |B |001 | | 001 | 7 | 7B | 9 | C, A |
|----------------------------------------------------| |END | B | -- |-- | B |
|--------------------------------------------------|
这个就是完整的处理流程,需要注意的是:
i. END不一定要发送的,可以通过加解压的有效数据长度来标识是否已经结束
ii.当组合的编码位数超过有效位数时,例如:如果发现一个新的组合,但是组合编码表已经满时,可以不再进行编码而直接发送当时的编码码字即可,而且重要压缩方和解压方的组合编码表一致,甚至可以清空所有的组合编码表并重新构造。