LZ77压缩算法解析

注:文章摘录自https://mp.weixin.qq.com/s?__biz=MjM5OTM0MzIwMQ==&mid=2652550432&idx=5&sn=7ff163dad49865f435488ed2836d7119&chksm=bcd2f02e8ba579381dac6bb247dff704e0472d474e886a691266114daae26df97fe163505251&mpshare=1&scene=24&srcid=0723DQWaW8MDysaoG2M19RnJ&key=3d8efa8bcd6863c35d648ef61c6619eae009ebf188fc6981338cd512a6c692e1f0e252d42b6bc12cc565486e795eb10907950fcc06978c9296a93a26d22daf91c4e295fe15f47694ecaaea434724ba44&ascene=0&uin=MjY5OTIzMzI0Mg%3D%3D&devicetype=iMac+MacBookPro12%2C1+OSX+OSX+10.13+build(17A306f)&version=12020810&nettype=WIFI&fontScale=100&pass_ticket=Ll9wGx1lm%2B0gmBCIywLWwrt5UttdwRnEeekg9dNm6zqCPIfbJw3eJWDLBI9V75WD

压缩方案有很多种,常见的就是有损和无损压缩。霍夫曼编码和LZ77(Lempel-Ziv-1977)都是无损压缩,其中霍夫曼是采用最小冗余编码的算法进行压缩,而LZ77是采用字典的方式进行压缩。

信息熵

数据为何是可以压缩的,因为数据都会表现出一定的特性,称为

绝大多数的数据所表现出来的容量往往大于其熵所建议的最佳容量。比如所有的数据都会有一定的冗余性,我们可以把冗余的数据采用更少的位对频繁出现的字符进行标记,也可以基于数据的一些特性基于字典编码,代替重复多余的短语。

前向缓冲区

每次读取数据的时候,先把一部分数据预载入前向缓冲区。为移入滑动窗口做准备。

滑动窗口

一旦数据通过缓冲区,那么它将移动到滑动窗口中,并变成字典的一部分。

短语字典

从字符序列S1...Sn,组成n个短语。比如字符(A,B,D) ,可以组合的短语为{(A),(A,B),(A,B,D),(B),(B,D),(D)},如果这些字符在滑动窗口里面,就可以记为当前的短语字典,因为滑动窗口不断的向前滑动,所以短语字典也是不断的变化。

LZ77算法原理

LZ77压缩算法采用字典的方式进行压缩,是一个简单但十分高效的数据压缩算法。其方式就是把数据中一些可以组织成短语(最长字符)的字符加入字典,然后再有相同字符出现采用标记来代替字典中的短语,如此通过标记代替多数重复出现的方式以进行压缩。

LZ77的主要算法逻辑就是,先通过前向缓冲区预读数据,然后再向滑动窗口移入(滑动窗口有一定的长度),不断的寻找能与字典中短语匹配的最长短语,然后通过标记符标记

滑动窗口和前向缓冲区

目前从前向缓冲区中可以和滑动窗口中可以匹配的最长短语就是(A,B),然后向前移动的时候再次遇到(A,B)的时候采用标记符代替。

压缩

当压缩数据的时候,前向缓冲区与移动窗口之间在做短语匹配的是后会存在2种情况:

找不到匹配时:将未匹配的符号编码成符号标记(多数都是字符本身)

找到匹配时:将其最长的匹配编码成短语标记。

短语标记包含三部分信息:(滑动窗口中的偏移量(从匹配开始的地方计算)、匹配中的符号个数、匹配结束后的前向缓冲区中的第一个符号)。

一旦把n个符号编码并生成响应的标记,就将这n个符号从滑动窗口的一端移出,并用前向缓冲区中同样数量的符号来代替它们,如此,滑动窗口中始终有最新的短语。通过图来进行解释:

初始化,因为滑动窗口没有匹配短语,所以记为标记A
滑动窗口移到A,缓冲区为BABC,没有匹配到短语,依然把B标记为B
滑动窗口在向右移6位时可以匹配到短语AB,AB长度为2,短语后面的字母为C,所以标记为(6,2,C)
滑动窗口向右移动4位时可以匹配到滑动窗口的短语BAB,长度为3,短语后面的字母为A,所以标记为(4,3,A)
在滑动窗口位移2的位置匹配到短语BC,将BC编码为(2,2,A)
缓冲区字符D,在滑动窗口中没有找到匹配短语,标记为D
缓冲区中没有数据进入了,结束

解压

解压类似于压缩的逆向过程,通过解码标记和保持滑动窗口中的符号来更新解压数据。

将字符A解码
将字符B解码
(6,2,C)解码,滑动窗口右移6位,短语长度为2,短语后面字母为A


同理将(4,3,A)解码
同理将(2,2,A)解码
将D解码

当解码字符标记:将标记编码成字符拷贝到滑动窗口中

解码短语标记:在滑动窗口中查找响应偏移量,同时找到指定长短的短语进行替换。

推荐阅读更多精彩内容