LZW压缩算法
其实关于LZW的算法网上已经有很多描述了,但其实很多描述都不到位。刚开始,我看了几篇关于LZW的博客,也没完全弄懂,感觉挺容易,就开始写程序实现,但结果却总是错的。为此,晚上睡觉都在想错在哪里。第二天一大早就再一次地仔细地调试程序,还是错,解码的结果与原字符串不一样。但仔细找原因又总感觉自己的程序逻辑没错。所以我逐磨着,估计是网上很多资料本来就没说清楚。后来找到一篇稍微权威些的博客,她把原LZW的算法流程图贴了出来,才发现解码过程和我想象中完全不一样。而且按照流程图进行写代码,程序立即变得简洁了。不得不感慨发明LZW的那三个人的匠心独运。
重新贴一下算法流程图,编码过程:
对理解编码有用的博客:http://www.cnblogs.com/jillzhang/archive/2006/11/06/551298.html
解码过程:
需要特别注意的是解码过程的流程10,我之前一直解码出错就是因为这里的原因,因为我每次都是将上次解码的结果与本次解码的结果相加然后添加到字典中,而实际的上次解码结果仅与本次解码的第一个字符相加添加到字典里。另外,还有一点想不通的是流程5、6,为什么在解码中如果没有找到本次码字时只需要把上次解码的字串与上次字串的第一个字符相加就可以得到本次解码结果了?
致谢:http://blog.csdn.net/abcjennifer/article/details/7995426
贴上代码:
编码过程:
data1 = "abcaabaabababccaaaa"#测试数据 data = [i for i in data1]#数据转换为列表 d = {'a':0, 'b':1, 'c':2}#初始字典 STRING = data[0]#流程1 i = 1 code = [] while i!=len(data): CHAR = data[i] #流程2 if d.has_key(STRING+CHAR): #流程3 STRING += CHAR #流程7 else: code.append(d[STRING]) #流程4 d[STRING+CHAR] = len(d) #流程5 STRING = CHAR #流程6 i += 1 #while循环-- 流程8 code.append(d[STRING]) #流程9 print code print d #编码结果:[0, 1, 2, 0, 3, 6, 1, 7, 4, 5, 6, 0]
解码过程:
decode = [] #初始解码结果 d = {0:'a', 1:'b', 2:'c'} #初始字典 OCODE = code[0] #流程1 decode.append(d[OCODE]) #流程2 i = 1 while i != len(code): NCODE = code[i] #流程3 if d.has_key(NCODE): #流程4 STRING = d[NCODE] #流程7 else: STRING = d[OCODE] #流程5 STRING += CHAR #流程6 decode.append(STRING) #流程8 CHAR = STRING[0] #流程9 d[len(d)] = d[OCODE] + CHAR #流程10 OCODE = NCODE #流程11 i += 1 #while循环-- 流程12 decode_str = ''.join(decode) print decode_str print decode_str == data1 print d