LZW压缩算法

其实关于LZW的算法网上已经有不少描述了,但其实不少描述都不到位。刚开始,我看了几篇关于LZW的博客,也没彻底弄懂,感受挺容易,就开始写程序实现,但结果却老是错的。为此,晚上睡觉都在想错在哪里。次日一大早就再一次地仔细地调试程序,仍是错,解码的结果与原字符串不同。但仔细找缘由又总感受本身的程序逻辑没错。因此我逐磨着,估计是网上不少资料原本就没说清楚。后来找到一篇稍微权威些的博客,她把原LZW的算法流程图贴了出来,才发现解码过程和我想象中彻底不同。并且按照流程图进行写代码,程序当即变得简洁了。不得不感慨发明LZW的那三我的的匠心独运。html

从新贴一下算法流程图,编码过程:算法

clip_image002

对理解编码有用的博客:http://www.cnblogs.com/jillzhang/archive/2006/11/06/551298.htmlapp

解码过程:测试

clip_image003

须要特别注意的是解码过程的流程10,我以前一直解码出错就是由于这里的缘由,由于我每次都是将上次解码的结果与本次解码的结果相加而后添加到字典中,而实际的上次解码结果仅与本次解码的第一个字符相加添加到字典里。另外,还有一点想不通的是流程五、6,为何在解码中若是没有找到本次码字时只须要把上次解码的字串与上次字串的第一个字符相加就能够获得本次解码结果了?编码

致谢:http://blog.csdn.net/abcjennifer/article/details/7995426spa

贴上代码:.net

编码过程:调试

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]

解码过程:code

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
相关文章
相关标签/搜索