LZ77压缩算法

基本介绍:


        LZ77算法是一种无损数据压缩算法,由Abraham Lempel和Jacob Ziv于1977年提出。它是一种字典编码方法,通过查找数据中重复出现的字符串,并用较短的标记来替代这些字符串,从而实现压缩。

        

算法原理:

      LZ77算法的核心是在前面的历史数据中寻找重复字符串,同时重复现象是具有局部性的,它的基本假设是,如果一个字符串要重复,那么也是在附近重复,远的地方就不用找了,因此设置了一个查找数据的滑动窗口。LZ77滑动窗口是32KB,那么就是往前面32KB的数据中去找,这个32KB随着编码不断进行而往前滑动。

      我们先手动设定一个窗口,这个窗口包含两个部分,其中之一是位于左半部分的字典区域,另一个是位于窗口右端的待编码区。然后我们在这个窗口内,将待编码区中出现的字符串在字典区进行查找,以此来达到压缩的目的。

  LZ77算法的输出是一个三元组,(off, len, char)分别表示是匹配字符串的偏移(在这里的偏移是匹配字符串离字典区右边的距离),第二个len是表示匹配字符的长度,第三个则是表示匹配之后的下一个字符。(偏移距离、匹配长度、下一个字符)

实现过程:


1. 初始化滑动窗口,填充待编码数据。
2. 在待编码区查找搜索窗中的最长匹配字符串。
3. 如果找到匹配字符串,输出(偏移值,匹配长度),窗口滑动匹配长度个单位。
4. 如果没有找到匹配字符串,输出(0, 0, 待编码区的第一个字符),窗口滑动一个单位。
5. 重复步骤2,直到待编码区为空。

示例说明:

示例1:aacaacabca(字典长度为6)

    编码过程:

    如下图所示,最开始字典为空,偏移距离和匹配长度均为0,因此当遇到第一个字符 a 时,得到的三元组为:(0,0,a)

    如下图所示,字典为:{a},字典中只有一个字符,能够匹配的只有空白区的a,此时,偏移距离为1,匹配长度为1,下一个字符为c,得到三元组:(1,1,c)

    如下图所示,字典为:{a a c},字典中有3个字符,匹配长度为aaca,偏移距离为4,这是由于字典中的aac与空白区的aac匹配,然后,空白区的下一个a与字典中的a匹配,因此匹配的只有字典中的aac三个字符,但是在空白区匹配了4个字符,得到三元组:(3,4,b)

    如下图所示:字典为:{c a a c a b},上一步中得到左侧编码区为:{a a c a a c a b},由于限定了字典长度为6,因此从左侧编码区的后面截取6个字符作为字典区;

    空白区为:{c a},与字典区的前两个匹配,因此匹配长度为2,偏移距离即空白区的c与字典区的匹配字符c的距离,为6,得到三元组:(6,2,0)

解码过程:

(0,0,a)     0偏移,0匹配,一个a

(1,1,c)     字典中有一个a,一个偏移,一个匹配,即aa,下一个c,得到aac

(3,4,b)     字典为:aac,3偏移,则在字典中第一个字符开始的第三个字符后面加匹配字符,4匹配,超过字典长度,则先复制一次字典,再循环+1位,得到aacaaca,下一个b,得到aacaacab

(6,2,0)     上一步得到编码区为:aacaacab,而字典长度为6,取后面6个字符作为字典区,偏移距离为6,在字典左侧第一个字符开始,第6个字符后面加字符,匹配字符数量为2,则复制字典中前两个字符,得到caacabca,这个字符串前面加上字典前面的aa,得到aacaacabca

示例2:aacaacabca(字典长度为3)

编码过程:

解码过程:

实际应用:

LZ77算法是一种无损数据压缩算法,广泛应用于多个领域,尤其是在需要流式压缩的场合。以下是LZ77算法的一些实际应用场景:

  1. 文件压缩:LZ77算法常用于文件压缩程序中,如gzip和zip文件的压缩。它通过查找文件中的重复字符串,并用较短的标记来替代这些字符串,从而实现压缩。

  2. 网络传输:在网络数据传输中,使用LZ77算法可以减少发送数据的大小,从而加快传输速度,减少带宽消耗。

  3. 视频和音频压缩:在多媒体数据压缩中,LZ77算法可以作为视频和音频压缩算法的一部分,用于减少文件大小,便于存储和传输。

  4. 数据库存储:数据库中存储的大量文本数据可以通过LZ77算法进行压缩,以节省存储空间。

  5. 实时系统:在需要实时数据压缩的系统中,如实时视频监控,LZ77算法可以用来实时压缩视频流。

  6. 归档和备份:在数据备份和归档过程中,使用LZ77算法可以显著减少备份数据的大小,便于存储和恢复。

存在问题和对应改进方向:

  1. 窗口大小限制:LZ77算法使用一个固定大小的滑动窗口,这意味着它只能查找到窗口内之前出现过的字符串。如果重复字符串出现在窗口之外,则无法被识别为重复,这限制了算法的压缩效率。可以通过增加窗口大小:虽然增加窗口大小可以提高压缩率,但这也会增加内存消耗和计算时间,因此需要计算增加多大窗口可以提高压缩率的同时,内存消耗和计算时间相对增加较少。

  2. 压缩比率:对于某些类型的数据,尤其是那些重复模式较少或模式非常长的文件,LZ77可能不会实现很高的压缩比率。可以通过使用更高级的字符串匹配算法来提高查找重复字符串的效率,如:KMP匹配算法等。

  3. 计算复杂性:LZ77算法在查找最长匹配时可能需要进行大量的字符串比较,这在数据量较大时会增加计算复杂性和时间,计算哪些循环是不是必要的,减少不必要的循环和比较。

  4. 内存使用:由于需要维护一个滑动窗口的缓冲区,LZ77算法可能会占用较多的内存资源,尤其是在处理大文件时。利用现代硬件的并行处理能力,如GPU或FPGA,或者通过对大文件分块压缩完再合并。

其它改进方向:

1、替换的重复字母长度问题

2、查找重复字符串的效率问题

3、结合具体场景的改进

例如:前处理:例如:传输场景,为了数据安全,数据分块,使得不同块数据压缩后的相似度与原始数据相似度较小,避免攻击者获得压缩前数据的分布信息

中处理:例如:传输场景:为了数据安全,当匹配区间多大时,可以使得压缩率最大,提高传输效率,逻辑:传输速度快,攻击者难以攻击

后处理:例如1:传输场景,由于设备硬件原因,解压速度慢,需要文件本身的解压速度快,什么样的匹配区间有助于提高解压速度;例如2:什么样的匹配区间有助于传输过程中一个数据损坏,容易通过其它数据修复。

LZ77算法的改进算法:

  1. LZSS算法:LZSS是对LZ77算法的改进,它在编码时增加了一个判断,当编码后的数据比原数据大时,就直接输出原数据,而不进行编码。这样可以避免LZ77算法在某些情况下压缩率不高的问题 。

  2. LZ78算法:LZ78算法是LZ77的另一个变种,它使用一个字典来存储已经出现过的字符串,并在读取数据流时,将新出现的字符串与字典中的字符串进行匹配。LZ78算法通过维护一个字符串字典来记录出现过的字符串,以此来替代LZ77中的滑动窗口和前向缓冲区,从而提高了压缩效率 。

  3. LZW算法:LZW算法是LZ78算法的改进版,由Terry Welch提出。LZW算法在编码过程中,将已经出现过的字符串存入字典中,并在读取数据流时,将新出现的字符串与字典中的字符串进行匹配。LZW算法通过动态更新字典的方式,进一步提高了压缩效率 。

  4. LZ-End:LZ-End算法是LZ77算法的扩展,它在查找匹配字符串时,不仅考虑当前滑动窗口中的内容,还考虑之前已经编码过的数据。这样能够提高匹配的概率,从而提高压缩比率 。

  5. LZ-B:LZ-B算法是LZ77算法的另一种改进,它通过使用双向匹配(向前和向后)来查找重复的字符串,从而提高压缩效率 。

  6. LZ-H:LZ-H算法是LZ77算法的另一种改进,它通过调整滑动窗口的大小,使得窗口大小可以根据数据的特性动态变化,以此来提高压缩效率 。

  7. LZ-Huffman:结合LZ77算法和Huffman算法,对LZ77算法产生的长距离-长度对进行Huffman编码,以进一步压缩数据 。

  8. LZ-Deflate:在zlib库中使用的Deflate算法实际上结合了LZ77算法和Huffman算法,它使用LZ77算法进行字符串匹配,然后使用Huffman算法对匹配结果进行编码,从而实现高效的压缩

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值