详解LZ77字典编码压缩和解压缩流程(典型的压缩算法)

字典编码本质上是将在字典中出现过的字符串使用一个索引值代替,以此来达到压缩目的。基于字典的压缩算法有很多,LZ77和LZ78是最原始的两个算法,后者是前者的变体,原理基本上相似。本文对LZ77字典编码的压缩和解压缩流程进行介绍。

一、什么是LZ77字典编码

LZ77算法是无损压缩算法,由以色列人Abraham Lempel发表于1977年,是典型的基于字典的压缩算法,现在很多压缩技术都是基于LZ77。

LZ77字典编码把整个滑动窗口分为2个区域,左侧为字典区,右侧为待编码区。

LZ77编码器在字典区查找,直到找到匹配的字符串。匹配字符串的开始位置与离字典区右边的距离称为“偏移值”,匹配字符串的长度称为“匹配长度”。LZ77在编码时,会一直在字典区中搜索,直到找到最大匹配字符串,然后输出一个三元祖(off, len, char),off表示偏移值,len表示匹配长度,char为待编码区第一个等待编码的字符。

偏移值实际上可以有两种,第一种是匹配字符串的开始位置离字典区左边的距离,第二种是匹配字符串的开始位置离字典区右边的距离,一般使用第二种。

二、LZ77编码的压缩流程

在编码前要指定滑动窗口的大小,这里设置为8,其中字典区窗口大小为5,待编码区窗口大小为3。
现在有字符串“AABCBBABC”,现在对其进行编码。
(1)编码开始,窗口初始位置如图
在这里插入图片描述
由上图可见,待编码区有“AAB”三个字符,此时字典区为空。现在编码第一个字符A,由于字典区为空,故匹配不到的字符串。当匹配不到字符串时,规定偏移值为0,匹配长度也为0,此时待编码区第一个等待编码的字符为A,故输出(0,0, A),然后滑动窗口右移一个单位,如下图
在这里插入图片描述
(2)如上图可知,此时待编码区为“ABC”。现在编码“A”,在字典区可以匹配到字符串"A",继续编码“AB”,由于在字典区没有可以匹配到的字符串,无法编码,因此只能编码"A"。
字典区匹配到的“A”的开始位置离字典区右边的距离为1,匹配字符串的长度也为1,待编码区第一个等待编码的字符为A,故输出(1,1,A),滑动窗口右移一个单位,如下图
在这里插入图片描述
(3)继续编码,此时待编码区为“BCB”。现在编码“B”,字典区没有匹配到,无法编码,输出(0,0,B),滑动窗口右移一个单位,如下图
在这里插入图片描述
(4)待编码区为“CBB”,现在编码“C”,字典区没有匹配到,无法编码,输出(0,0,C),滑动窗口右移一个单位,如下图
在这里插入图片描述
(5)待编码区为“BBA”,现在编码“B”,字典区可以匹配到,继续编码“BB”,字典区匹配不到,无法编码,输出(2,1,B),滑动窗口右移一个单位,如下图
在这里插入图片描述
(6)待编码区为“BAB”,现在编码“B”,字典区可以匹配到,继续编码“BA”,字典区匹配不到,无法编码,输出(3,1,B),滑动窗口右移一个单位,如下图

字典区有从左到右匹配的,上图中字典区第一个“B”离字典区右边的距离为3。

在这里插入图片描述

(7)待编码区为“ABC”,现在编码“A”,字典区可以匹配到,继续编码“AB”,字典区也可以匹配到,继续编码“ABC”,字典区能够匹配。待编码区中的字符都编码完了(即编码位置已经达到了待编码窗口右边界,如果继续编码,就会超过窗口边界),输出(5,3,A),长度3,滑动窗口右移3个单位,如下图
在这里插入图片描述
此时待编码缓冲区为空,结束编码。所以,当我们输入字符串“AABCBBABC”最后得到的三元组序列为(0,0, A),(1,1,A),(0,0,B),(0,0,C),(2,1,B),(3,1,B),(5,3,A)

上面是最原始的匹配方法,具体实现时可以进行优化,比如利用字典树(TrieTree)匹配。

三、LZ77编码的解压缩流程

解压缩码相对起来就简单许多了,就是编码流程的逆过程,具体流程如下

  1. 按需读取三元组进行,并进行解压
  2. 如果off=0,表示原字符,直接输出char
  3. 如果off<>0,读取字典中的字符,找到偏移值为off的位置(距离字典右侧的偏移),截止len个字符,比如 dict = “ABCD”,编码为(3,2,E),找到偏移值为3的位置(即B),截取2个字符,输出为BC
  4. 获取下一个三元组,直到所有的三元组解析完毕

现在,输入三元组序列为(0,0, A),(1,1,A),(0,0,B),(0,0,C),(2,1,B),(3,1,B),(5,3,A),字典大小为5,具体解压如下:

步骤输入当前字典解码输出
1(0,0, A)AA
2(1,1,A)AAAA
3(0,0,B)AABAAB
4(0,0,C)AABCAABC
5(2,1,B)AABCBAABCB
6(3,1,B)AABCBBAABCBB
7(5,3,A)ABCBBABCAABCBBABC

参考资料

  1. LZ77 压缩和解压缩
  2. 压缩算法之字典编码(上)
  3. 基于LZ77算法的文件压缩铺垫
  • 20
    点赞
  • 90
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Linux系统中常用的压缩解压缩命令有gzip、tar、zip、unzip等。这些命令可以压缩文件或目录,减小文件占用的空间,也可以解压缩已经压缩的文件或目录,还可以将多个文件合并成一个文件。 gzip命令可以将文件压缩成gzip格式,命令格式为:gzip [选项] 文件名。选项有-r(递归压缩),-d(解压缩),-c(输出到标准输出),-t(测试文件是否完好)等。 tar命令可以将文件或目录打包成tar格式,命令格式为:tar [选项] 文件名。选项有-c(创建归档文件),-x(解压缩),-v(显示详细信息),-f(指定归档文件),-z(使用gzip格式压缩)等。 zip命令可以将文件或目录压缩成zip格式,命令格式为:zip [选项] 压缩文件名 被压缩文件或目录名。选项有-r(递归压缩),-d(删除压缩文件中指定文件),-j(将文件存储在压缩文件中时去掉所有的路径信息),-m(压缩后删除被压缩的文件)等。 unzip命令可以解压缩zip格式的文件,命令格式为:unzip [选项] 文件名。选项有-l(列出zip文件的内容),-t(测试zip文件的完整性),-q(不显示解压缩过程),-C(解压缩到指定目录)等。 以上命令只是Linux系统中常用的压缩解压缩命令,还有很多其他的命令,需要根据具体需求选择使用。压缩解压缩命令的使用可以提高文件操作的效率,减少文件占用的空间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

雷恩Layne

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值