LZW编码原理
LZW的编码思想是不断地从字符流中提取新的字符串,然后用码字表示这个新字符串。这样用码字去替换字符流,生成码字流,可以达到压缩数据的目的。
LZW编码是围绕称为词典的转换表来完成的。LZW编码器通过管理这个词典完成输入与输出之间的转换。LZW编码器的输入是字符流,字符流可以是用8位ASCII字符组成的字符串,而输出是用n位(例如12位)表示的码字流。
LZW编码算法的步骤如下:
- 步骤1:将词典初始化为包含所有可能的单字符,当前前缀P初始化为空;
- 步骤2:当前字符C=字符流中的下一个字符;
- 步骤3:判断P+C是否在词典中:
- (1)如果“是”,则用C扩展P,即让P=P+C,返回到步骤2;
- (2)如果“否”,则输出与当前前缀P相对应的码字W;将P+C添加到词典中;令P=C,并返回到步骤2。
LZW解码原理
LZW解码算法开始时,译码词典和编码词典相同,包含所有可能的前缀根。具体解码算法如下:
- 步骤1:在开始译码时词典包含所有可能的前缀根;
- 步骤2:令CW:=码字流中的第一个码字;
- 步骤3:输出当前缀-符串string.CW到码字流;
- 步骤4:先前码字PW:=当前码字CW;
- 步骤5:当前码字CW:=码字流的下一个码字;
- 步骤6:判断当前缀-符串string.CW 是否在词典中:
- (1)如果”是”,则把当前缀-符串string.CW输出到字符流。当前前缀P:=先前缀-符串string.PW。当前字符C:=当前前缀-符串string.CW的第一个字符。把缀-符串P+C添加到词典。
- (2)如果”否”,则当前前缀P:=先前缀-符串string.PW。 当前字符C:=当前缀-符串string.CW的第一个字符。 输出缀-符串P+C到字符流,然后把它添加到词典中。
- 步骤7:判断码字流中是否还有码字要译:
- (1)如果”是”,返回步骤4;
- (2)如果”否”,结束。
实验步骤
1.调试LZW的编码程序,输入一个文本文件,得到输出的LZW编码文件
输入的文本文件为:
调试程序,设置命令参数:
得到输出的LZW编码文件:
部分编码词典内容如下:
2. 以步骤一得到的编码文件作为输入,编写LZW的解码程序
解码程序详细解析:
//解码
void LZWDecode( BITFILE *bf, FILE *fp){
int character;
int new_code, last_code; //new_code表示码流中的下一个码字,last_code表示上次解码的码字
int phrase_length; //解码字符串的长度
unsigned long file_length; //文件长度
file_length = BitsInput(bf, 4 * 8); //编码后压缩文件的大小
if (-1 == file_length) file_length = 0;
InitDictionary(); //初始化字