LZW编码的学习与实现

这里写图片描述

大家好,现在是2020年5月19日,不知不觉5年过去了,看到最近还有很多人评论我的这篇文章,非常的开心和满足,显然我写这篇文章所做的微小贡献帮助到了一些人。今天我从头到尾再看了一遍我写的东西,还是有一些东西没有描述清楚,比如下面第一个表里里面,dictionary 那一列里面的 xx:5,我就一直没明白什么意思。另外,一些朋友在评论区对256,257是怎么来的感到疑惑,我都会对文章做一次修订,将这些内容描述清楚,谢谢大家。

Preface

看了一天,感觉终于搞明白了一点(代码终于写对了),编码过程大四的时候学过一点点,按部就班的按照步骤来做就行了,解码过程貌似课堂上老师没讲,自己看wiki上的讲解和example搞懂了。

LZW全称Lempel–Ziv–Welch,就是这个三个人搞出来的。

LZW的工作思路,考虑一段数据,abcabcabc,对于这样的一段数据,如果不做任何处理和压缩,假设每个字符用一个字节来表示,直接存储的空间应该是9字节。详细说明下:
下表是我们dictionary,也就是码表,字符与编码的对应。

character decimal binary
a 1 0000 0001
b 2 0000 0010
c 3 0000 0011

观察上面的字符串,发现abc是重复的,如果abc能用一个字节来表示的话,那么,只需要3字节存储就足够了。

character decimal binary
abc 1 0000 0001

OK,LZW就是这个尿性,它就是想这么搞。

Encoding

基本思想

编码的基本思想是这样的,首先我们有一个码表或者称为dictionary,里面只定义单个字符和编码,比如0-9a-zA-Z这些,其实ASCII码中的所有全部都放进去都可以。

也就是说通常用十进制数0-255来表示单一字符(single character)。

然后我们开始读取字符串,很显然对于任何常规字符串,每个single character都可以得到一个码字,但是如果我们不做处理的话,那么n个字符encode后,就是n个码字了完全没有压缩。

所以,再边读取的时候,一边开始对dictionary进行扩增,不断的将single character拼接成dictionary中不存在的符号(symbol),扩充dictionary,这样下次再次遇到这样的组合,就可以使用有一个码字表示了。

流程

说实话,用纯文字描述还真的不是很好描述,于是我画了一个流程图来描述这样一个过程。
这里写图片描述
就是上面这个图了,代码只要照着这个写就能搞定问题。但出于尊重,还是要讲解下比较好。
首先我们需要两个暂存器,P和C,为啥叫这个名字呢。(当时上学那会,老师给的是p和s,完全不知道意义)

P -> Previous -> 表示之前的字符
C -> Current -> 表示当前读取的字符

然后我们考虑字符串abcbcabcabcd

来,按步骤演算一下:

首先我们需要一个dictionary,简单考虑,只考虑a-d,4个英文小写字母吧。这里想表达的意思是,整个宇宙全世界只有a-d 4个英文字母,我们的ascii表中也只有 4 个字母。

symbol decimal
a 1
b 2
c 3
d 4
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值