LZW字典编码

字典编码思想

字典编码是一种自适应编码,利用了数据中存在的重复信息来扩充字典,并及时进行编码。字典编码属于一遍编码,不同于一般压缩编码所利用两遍编码得到统计信息后在编码传输,因此有可能在一些情况中压缩后的码率反而大于直接传输的情况。

LZW 编码步骤

步骤1:将词典初始化为包含所有可能的单字符,当前前缀P初始化为空。

步骤2:当前字符C=字符流中的下一个字符。

步骤3:判断P+C是否在词典中


(1)如果“是”,则用C扩展P,即让P=P+C,返回到步骤2。


(2)如果“否”,则与当前前缀P相对应的码字W;P+C添加到词典中;P=C,并返回到步骤

由于字典编码的范例老师已经给出,就不在这里再复制黏贴了,写一下我觉得重要的地方叭:
1、首先初始化函数InitDictionary()初始化了一个char型变量可以包含的全部256个字符,给出了兄弟节点,但是把母节点和子节点设为-1.
2、InDictionary(character, string_code)函数判断string+character是否在字典中,如果在字典中,则继续扩展并且返回继续判断,如果不在则将这个字符串添加入字典中。

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)如果”否”,结束。

LZW字典编码_第1张图片

结果报告

为了测试解码端对于特殊情况时的解码,因此特意设置了连续出现aba的情况,输入文件字符串为abbababac。
编码后我们可以看到数据是这样的:
在这里插入图片描述
前面的0000 0009 是指这个文件有9个字节。后面可以看到是a,b,b接下来ab被编成256,同时我们知道bb在字典中是257,ba是258,aba是259,因此编码得到的结果是,a b b 256 259 c
再次进行解码,得到的文件数据依然是abbababac。

同时,原本文件是9个字节,然而编码以后文件13个字节,是因为为了存更多的字典数据,因此原本一个字节的字符都用两个字节表示了,必须要文件编码的全部的字符串平均大于两个字符才能起到压缩的作用。

你可能感兴趣的:(LZW字典编码)