词典编码

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。


现在将窗口向后滑动3(2+1)个字符,窗口中的内 容为:dbbccaaaba,剩余字符为eaaabaee,下一个 字符 e 在窗口中没有匹配,我们输出三元组:(0, 0, e)。
abcdbbccaaabaeaaabaee

又将窗口向后滑动 1 个字符,其中内容变为: bbccaaabae。这时发现,要编码的 aaabae 在窗口 中存在(off = 4, len = 6),其后的字符为 e,可以输 出:(4, 6, e)。
LZW算法的框架
1.
2.
3. 4.
5.
6. 7. 8.
void LZW(void){ 将所有单字符放入字典D中; read(w); while(还有字符未处理完) { read(k); if ( w + k D) w = w + k; else {write(w在字典中的序号); append(dictionary, w + k); w = k;} }
LZ77算法

LZ77 算法又称为“滑动窗口压缩” ,如下图:
LZ77 算法的基本流程
重复进行以下处理,直至所有数据处理完毕: 1、从当前压缩位臵开始,考察未编码的数据,并试图在滑 动窗口中找出最长的匹配字符串, 2、如果找到,输出三元符号组(off, len, c),其中off为窗口 中匹配字符串相对窗口边界的偏移,len为可匹配的长度, c为下一个字符;将窗口向后滑动len + 1个字符。 3、如果未找到,输出三元符号组(0, 0, c),其中c为下一个 字符;将窗口向后滑动 1个字符。

词典编码法的种类很多,归纳起来大致有两类。

第一类词典法的想法是企图查找正在压缩的字符 序列是否在以前输入的数据中出现过,然后用已 经出现过的字符串替代重复的部分,它的输出仅 仅是指向早期出现过的字符串的“指针”。

第二类算法的想法是企 图从输入的数据中创建 一个“短语词典 (Dictionary of the Phrases)”,这种短语 不一定是具有具体含义 的短语,它可以是任意 字符的组合。编码数据 过程中当遇到已经在词 典中出现的“短语”时, 编码器就输出这个词典 中的短语的“索引号”, 而不是短语本身。
词典编码

根据这一思路,你能从下面这幅图中读出其中包含的 原始信息吗?
词典编码

有许多场合,开始时不知道要编码数据的统计特性, 也不一定允许你事先知道它们的统计特性。因此, 人们提出了许许多多的数据压缩方法,企图用来对 这些数据进行压缩编码,在实际编码过程中以尽可 能获得最大的压缩比。这些技术统称为通用编码技 术。词典编码(Dictionary Encoding)技术就是属 于这一类,这种技术属于无损压缩技术。 词典编码的根据是数据本身包含有重复代码这个特 性。例如文本文件和光栅图像就具有这种特性。
压缩码 原字符串

序号
a b c 1b 2a 4c 3b 5a 1 2 3 4 5 6 7 8
对于字符串 “ababcbaaaaaaaa”,得 到的字典如右:
a b c ab ba abc cb baa
压缩后的编码为: ab的压缩码 前一个字的最后 单字符 字符是下一个字 {a,为1b,即第 b, c } + 一个字后面 {1, 的开始,所以这 2, 4, 3, 5, 1, 9, 10} 里是ba。 跟符号b。 单字符可事先约定, 从而无需传输。

aa aaa
aaaa
1a 9a
10a
9 10
11
LZW解压缩算法
1. 2. 3. 4.
5.
6. 7.
8.
9. 10.
void unLZW(void){将所有单字符放入字典D; orign_len = length(D); i = orign_len + 1; while (还有编码未处理完) { read(k); ch=first_char ( D[k] ); /*D中第k行首字符 */ if ( i > orign_len + 1) D[i – 1] =D[i – 1] + ch; D[i] = D[k]; /* 生成本行字符串的前一部分 */ write(D[k] ); /* 输出还原后的数据 */ i:=i+1; }}

假设窗口的大小为 10 个字符,我们刚编码过的 10 个字符是:abcdbbccaa,即将编码的字符为: abaeaaabaee。

首先发现,可以和要编码字符匹配的最长串 为 ab (off = 0, len = 2), ab 的下一个字符为 a, 我们输出三元组:(0, 2, a)。
窗口 abcdbbccaaabaeaaabaee
LZ算法


1977 年,Jacob Ziv 和 Abraham Lempel发表了论文 《顺序数据压缩的一个通用算法》。1978 年,他们发 表了该论文的续篇《通过可变比率编码的独立序列的 压缩》。 这两篇论文提出的两个压缩技术被称为 LZ77 和 LZ78 算法。它们的思路和字典法颇为相似,因此,人们将 基于这一思路的编码方法称作字典式编码。字典式编 码不但在压缩效果上大大超过了哈夫曼编码,而且, 对于好的实现,其压缩和解压缩的速度也异常惊人。
3、如何查找匹配串


限制可匹配字符串的最大长度(例如 20 个字节), 按照大小顺序组织成二叉有序树。在这样的二叉有 序树中进行字符串的查找,其效率是很高的。 当然,也可以采用KMP、KR、BM等快速串匹配算 法来依次进行长度为20、19、18……的模式匹配。
LZ78算法
LZ78算法的基本思路与LZ77算法类似,也是 利用已经处理过的编码信息,但它发生匹配时, 不是保存一个三元组,而是一个二元组:匹配 位置和不匹配的第一个字符。同时,还要将这 个字符串保存到内存中,为此,它需要一个不 断增长的编码字串表(字典)。 与LZ77相比,LZ78的最大优点是在每个编码 步骤中减少了字符串比较的数目,而压缩率与 LZ77类似。

词典编码


说起来,字典模型的思路相当简单,我们日常生活中就 经常在使用这种压缩思想。我们常常跟人说“奥运会”、 “IBM”、“TCP”之类的词汇,说者和听者都明白它们指 的是“奥林匹克运动会”、“国际商业机器公司”和 “传输控制协议”,这实际就是信息的压缩。 我们之所以可以顺利使用这种压缩方式而不产生语义上 的误解,是因为在说者和听者的心中都有一个事先定义 好的缩略语字典,我们在对信息进行压缩(说)和解压 缩(听)的过程中都对字典进行了查询操作。字典压缩 模型正是基于这一思路设计实现的。


如对符号串“ababcbabaaaaaaa”编码,需要的字典:
原字符串 a b ab c ba baa aa aaa
压缩码 0a 0b 1b 0c 2a 5a 1a 7a
序号 1 2 3 4 5 6 7 8
LZ78算法的框架
1.
2. 3.
4.
5. 6.
7.
8. 9.
10.
11.
void LZ78(void) { 将字典D置空; while (还有字符未处理完) #w表示w在字 {current= 0; goon = 1; read(w); 典中的序号 while ( goon ) { if (w D) {current = #w; read(k); w = w + k;} else goon = 0; } append(D, w); /*将字符串w放到字典的尾部*/ w = last_char(w); /* 取字符串w的末尾字符 */ write(current, w); /*输出匹配位置和不匹配字符 */ }}
词典编码
词典编码
以Huffman编码为代表的压缩模型都是基于对 信息中单个字符出现频率的统计而设计的,直 到 70 年代末期,这种思路在数据压缩领域一 直占据着统治地位。 在我们今天看来,这种情形在某种程度上显得 有些可笑,但事情就是这样,一旦某项技术在 某一领域形成了惯例,人们就很难创造出在思 路上与其大相径庭的哪怕是更简单更实用的技 术来。
基本思想
基本思想是:构造一个字典,将信息中反复出现 的字符串,登记为较短的字符串,解码时对这种 字符串,通过查字典,转换为原字符串。 该算法的原理很简单,但要真正实现却很困难, 因为它存在几个长期困扰着研究者的难点: 1、如何找到这些重复出现的字符串? 2、如何找到尽量长的字符串被替代? 3、怎样选用较短的字符串?如何区分原始信息中就 已经存在的用于代替的字符串?
词典编码


最简单的情况是: 我们拥有一本预先定义好的字典。例如,我们要对一 篇中文文章进行压缩,我们手中已经有一本《现代汉 语词典》。那么,我们扫描要压缩的文章,并对其中 的句子进行分词操作,对每一个独立的词语,我们在 《现代汉语词典》查找它的出现位置,如果找到,我 们就输出页码和该词在该页中的序号,如果没有找到, 我们就输出一个新词。 这就是静态字典模型的基本算法了。
LZW算法



LZ78算法很难一次匹配到更长的字符串,而且,它所 保存的信息量仍然有冗余,因为如果每一个字符都一 定能匹配成功的话,也可以不需要保存匹配不成功的 字符。 LZW算法的基本思路就是要尽量“拉长”这些串,为 此,它将LZ78算法中的每一个被分割的子串的最后一 个字符作为下一个子串的开始。当然这么做肯定会增 加字典的长度。而且需要先将所有可能出现的单字符 先放到字典中以保证单字符一定能匹配成功。 WinZIP,WinRAR等压缩工具及GIF、PNG等文件格 式都是LZ系列算法的受益者。
LZ77 算法的讨论
1、编码方法
分量off与窗口的大小有关,完全可以用固定 的位数来表示它。 分量len可以使用一种变长的编码方式来表示 该长度值。 字符c,用8个二进制位对其编码。

2、输出方式

原始LZ77 算法即使没有匹配,仍然需要输出一个 len = 0的三元组来表示单个字符,还可以设计出 另外一种更为有效的输出方式:将匹配串和不能 匹配的单个字符分别编码、分别输出,输出匹配 串时不同时输出后续字符。

LZ算法


1977 年,Jacob Ziv 和 Abraham Lempel发表了论文 《顺序数据压缩的一个通用算法》。1978 年,他们发 表了该论文的续篇《通过可变比率编码的独立序列的 压缩》。 这两篇论文提出的两个压缩技术被称为 LZ77 和 LZ78 算法。它们的思路和字典法颇为相似,因此,人们将 基于这一思路的编码方法称作字典式编码。字典式编 码不但在压缩效果上大大超过了哈夫曼编码,而且, 对于好的实现,其压缩和解压缩的速度也异常惊人。

压缩码为: {1, 2, 4, 3, 5, 1, 9, 10}

首先将单字符放入字典。 orign_len = length(D) = 3; i = orign_len + 1 = 4; read(k); k = 1; ch=first_char (D[k]) = a; ∵i orign_len + 1 ∴D[4] = D[1]; i = i + 1 = 5
词典编码

这两个以色列人在数据压缩领域做出了杰出贡献的, 因为正是他们打破了Huffman 编码一统天下的格局, 带给了我们既高效又简便的“字典模型”。 至今,几乎我们日常使用的所有通用压缩工具,象 WinZip,RAR……甚至许多硬件如网络设备中内置的 压缩算法,无一例外,都可以最终归结为这两个以色 列人的杰出贡献。
abcdbbccaaabaeaaabaee

最后又将窗口向后滑动 7 个字符。这样,我们将 可以匹配的字符串都变成了指向窗口内的指针, 并由此完成了对上述数据的压缩。
abcdbbccaห้องสมุดไป่ตู้abaeaaabaee
LZ77 算法的解压缩

LZ77 算法的解压缩的过程十分简单,只要我们像 压缩时那样维护好滑动的窗口,随着三元组的不 断输入,我们在窗口中找到相应的匹配串,缀上 后继字符 c 输出(如果 off 和 len 都为 0 则只输出 后继字符c ),即可还原出原始数据。
词典编码



你一定可以发现,静态字典模型并不是好的选择。 首先,静态模型的适应性不强,我们必须为每类 不同的信息建立不同的字典; 其次,对静态模型,我们必须维护信息量并不算 小的字典,这一额外的信息量影响了最终的压缩 效果。 所以,几乎所有通用的字典模型都使用了自适应 的方式,也就是说,将已经编码过的信息作为字 典,如果要编码的字符串曾经出现过,就输出该 字符串的出现位置及长度,否则输出新的字符串。
相关文档
最新文档