d4 1.docx
《d4 1.docx》由会员分享,可在线阅读,更多相关《d4 1.docx(43页珍藏版)》请在冰豆网上搜索。
d41
LZ77算法与模式匹配KMP算法的结合及算法实现
张绮雯
计算机科学系99级
99184085
[摘要]
基于字典的数据压缩算法是目前大多数通用文本压缩工具的首选。
本文深入探讨了基于字典的压缩算法LZ77,创造性地提出了把LZ77与模式匹配的KMP算法相结合的思想,解决LZ77的性能瓶颈问题,并编程实现了LZ77算法。
本文首先简单介绍了数据压缩的意义,理论基础和LZ77算法的背景,然后第二章深入探讨了LZ77算法,指出了LZ77算法的性能瓶颈,并提出一种不同于目前流行的通用压缩算法的方案,即把LZ77与KMP算法相结合。
接下来第三章深入分析了KMP算法,并研究了它要应用于LZ77必须作出哪些调整。
第四章具体介绍了如何实现本文提出的算法,并指出编程实现算法时进一步作出三方面的改进:
将窗口虚拟“滑动”;对匹配串的进行变长编码;单个字符和表示匹配串的元组混合输出,从而进一步改进程序的压缩性能。
第五章分析了本文的算法并提出进一步的研究工作。
附录给出了本文实现的压缩程序的源代码。
目前大多数的通用压缩程序是通过建立特殊数据结构来解决匹配串的快速查找,如二叉搜索树,hash表,trie树等,要付出一定的代价去维护这些复杂的数据结构。
本文提出的算法截然不同,不需要建立和维护任何特殊的数据结构,只需巧妙地把KMP和LZ77结合,这正是本算法的特色所在。
一、前言
(一)数据压缩的简介、必要性和意义
数据压缩技术在当今这个信息化时代得到了广泛的应用。
究竟,什么是“数据”?
什么是“数据压缩”?
所谓“数据”,通常是指信源所发信号的数字化表示或记录,包括数值、文本、图象、声音和影像等类型。
“数据压缩”,就是以较少的数码表示信源所发的信号,减少容纳给定信息集合或数据采样集合的信号空间,或者更简单来说,就是去掉信息中的冗余,以更少的数码来“进一步”地“表示”信号的原始数据表示。
数据压缩的过程是怎样的呢?
可以说:
数据压缩=模型+编码。
一般来说,数据压缩包括取得一个符合流并将它们变换成代码,如果代码的结果流规模比原始符号总的规模小,就成功实现了压缩。
模型用于处理输入符号并确定输出哪个或那些代码的数据和规则的一个集合。
编码程序用来产生基于模型所确定的概率的适当代码,以得到尽可能紧凑的压缩码流。
研究表明,大多数信息的表达都存在着一定的冗余度,通过采用一定的模型和编码方法,可以降低这种冗余度,从而达到压缩的效果。
当今时代是一个“信息爆炸”的时代,数据压缩已经成为了非常必要的技术。
看看一些具体的数字:
一张A4(210mm×297mm)幅面的照片,若用中等分辨率(300dpi)的扫描仪按真彩色扫描,共有(300×210/25.4)×(300×297/25.4)个象素,每个象素占3个字节,其数据量为26M字节;一颗卫星每半小时即可发回一次全波段数据(5个波段),每天的数据量可达1.1GB;采样率较低的数字电话,按每一取样用8位压扩量化,通常其数码率也需要8×8=64kbps。
由此可见,面对当今如此大量的数据,存储器的存储,通信干线信道的带宽,以及计算机的处理速度都受到了极大的压力。
尽管计算机的存储能力越来越大,但在这个信息时代,人们仍常常感到存储空间不够用,节省每一比特都是有实际意义的。
另一方面,如此大量的数据传输,给本来就已经非常紧张的网络带宽变得更加不堪重负。
因此,无论从存储还是传输的角度看,数据压缩都是有意义的。
数据压缩的好处有:
1节省存储空间:
数据压缩后能节省存储器、磁盘、磁带、光盘等数据存储介质的空间,降低存储费用。
2提高传输效率:
压缩数据,意味着能减少传输给定消息集合所需要的时间,较快地传输各种信源,降低信道占有费用。
3节省网络带宽:
把数据压缩能节省传输给定消息集合所要求的带宽,在现有通信干线上开通更多的并行业务。
总之,这个时代人们更迫切地要求减少数据存储空间,数字系统的成本几乎按位计算,如果不进行数据压缩,无论存储或传输都很难实用化,数据压缩的作用及其社会效益、经济效益将越来越明显。
(二)信息理论基础
经典的数据压缩技术,建立在信息理论的基础上。
信息论是数学的一个分支,40年代由在贝尔实验室工作的ClaudeShannon首创。
数据压缩涉及到冗余问题,一条消息中的冗余信息要占用额外的位来编码,如果去除这些额外信息,将减少消息的量,因此数据压缩进入信息论领域。
下面探讨一下与有关数据压缩的理论。
信息论使用术语Entropy(“熵”)来表示一条信息中真正需要编码的信息量,消息的熵越高,所含的信息就越多。
记字符Ak出现的概率为Pk,按概率的公理化定义,必须有:
0≤Pk≤1(k=1,2,3,…m),∑Pk=1
则字符Ak的熵定义为:
I(Ak)=-log2(Pk)
整条消息的熵就是所有单个符号熵的数学期望值,记信息为X,则:
H(X)=∑Pk*I(Ak)=∑(Pk*-log2(Pk))(k=1,2,3,…m)
信息论中已经证明,熵具有极值性,是数据压缩的理论极限。
设字符Ak的编码长度为Lk,熵的极值性表现为:
H(X)=∑(Pk*-log2(Pk))≤∑(Pk*Lk)(k=1,2,3,…m)
信源的冗余度可能隐含在信源符号的非等概率分布之中,也可能隐含在信源间的相关性之中。
数据压缩的途径有:
①获取字符概率,使对各字符的编码长度接近它的熵;②去除各信源分量间的相关性③利用条件概率进行编码④通过联合概率计算极限熵,进行编码。
(三)LZ77算法的背景
1977年和1978年,两位以色列人JacobZiv和AbrahamLempel发表了论文“顺序数据压缩的一个通用算法”(AUniversalAlogrithemforSequentialDataCompression)以及“通过可变比率编码的独立序列的压缩”(CompressionofIndividualSequencesviaVariable-RateCoding),在这两篇论文中提出的压缩算法被称为LZ77和LZ78。
这两种算法开创了基于字典的方法的新境界,使压缩技术得到了空前的革命。
因为在此之前研究的压缩模型都是基于对信息中单个字符出现频率的统计的:
Shannon和R.M.Fano提出了最早的对符号进行有效编码从而实现数据压缩的Shannon-Fano编码方法;Huffman于1952年发表了论文“最小冗余度代码的构造方法”(AMethodfortheConstructionofMinimumRedundancyCodes),提出了完全依据字符出现概率来构造平均长度最短的异字头码字,称作Huffman编码。
直到七十年代的末期,数据压缩领域几乎一直被Huffman编码及其分支所垄断,数据压缩的研究工作主要集中于熵、字符和单词频率以及统计模型等方面,直到基于字典的编码的出现,才突破了这一切。
基于字典的编码不但能在压缩效果上超越Huffman,而且能不增加程序对系统资源和时间的需求,只要实现方法良好,其压缩和解压缩的速度是很好的。
基于统计模型的压缩算法通过将符号编码成比原符号串使用更少位数的位串来达到压缩目的,不仅要精确的计算符号的概率,而且概率必须偏离均匀值,偏离得越少,压缩效果越差。
基于字典的模型则将可变长的符号串作为一些独立的标记来编码,该标记形成字典的一个索引,如果标记长度小于它所代替的短语,就实现了压缩。
这种方法容易理解,符合人们的思维习惯,而且模型维护简单,编码输出简单,效果好,速度快。
由于字典模型的优点,LZ77及其变体算法成为极具吸引了的压缩算法,像PKZIP和HaruyasuYoshizaki的LHarc以及RobertJung的ARJ这些流行的通用程序都使用了LZ77算法的变体。
基于字典的LZ77、LZ78及其变体LZW几乎垄断了当今的通用数据压缩领域,我们日常使用的通用压缩工具,像WinZip,RAR,GZip,ACE,ZOO,TurboZip,Compress,JAR……甚至许多硬件如网络设备中内置的压缩程序,都可以最终归结为这些算法及其变种。
二、基于字典的压缩算法LZ77探讨
(一)算法的基本思路
基于字典压缩的基本思想十分简单,很容易理解:
我们经常说“世贸”,“CPU”等词,大家都明白这指的是“世界贸易组织”,“中央处理器”,其实这已顺利完成了信息压缩与解压的过程:
说的人和听的人头脑中都有一本相同的缩略语字典,说(压缩)和听(解缩)的过程中都对字典进行查询操作,从而实现现压缩和解压。
再看一个例子。
假如我们手上有一本英语词典,要对以下一段话进行压缩:
dictionarymethodsarebothsimpleandpopular.输出的编码如下:
101.2388.44.650.11470.93.8411.13
编码的意义是第一部分表示词典的页码,第二部分表示该单词是该页中的第几个,如101.2表示dictionary这个单词是第101页的第2个单词。
所以这种方法的基本思想就是:
有一本压缩者和解压者共同的词典,对要压缩的一段文本进行扫描,对其中的句子进行分词操作,得到的每一个独立的词语,在词典中查找它的位置,并输出页码和该词在该页中的序号。
解压过程更简单,只要在指定的词典位置查出该词就是了。
这种方法是否真能达到压缩效果呢?
看回上面的例子,假设词典共有500页,每页不超过128个单词,则页码可以用9位二进制位编码,页内序号可以用7位二进制位编码,每个单词一共用16位编码。
上面这段话的编码长度是16×7=112位二进制位。
而还没压缩前,每个单词的ASCII码8位,例子中的那段话一共要用8×46=368位二进制位。
(二)自适应模型胜于静态模型
字典模型有两种:
静态和自适应。
在静态字典模型中,字典在压缩开始之前就已经建立,并且不会随着数据的压缩过程而改变。
静态字典的优点是不需要在压缩和解压过程中维护字典,因此压缩和解压的实现可以比较简单。
但是,静态字典模型用得很少,因为它存在不少缺点。
首先,静态模型的适应性不强,必须为每类不同的信息建立不同的字典,为某类信息建立了字典后,该字典通常不能被其它类型的信息重用;其次,静态模型必须维护信息量并不算小的字典,并且必须解决如何将字典从编码程序传递到解码程序的问题,这一额外的信息量可能会严重影响压缩效果,特别对于小文本。
所以目前静态模型只用于特殊目的、独立实现的应用,并不是通用的。
LZ77应用自适应字典模型。
自适应模型在压缩前不预先建立字典,而是在压缩过程中建立和维护字典,也就是说,将已经编码过的信息作为字典,如果要编码的字符串曾经出现过,就输出该字符串的出现位置及长度,否则输出新的字符串。
过程描述如下:
While(文本还没扫描结束){
Word=read_word();
Look_up(word,dictionary);
If(找到匹配短语){
Output(word);
Add_to_dictionary(word);
}elseOutput(word_position);
}
(三)算法描述——滑动的窗口
LZ77压缩可以称为滑动窗口压缩,因为它用到的主要数据结构是一个可以滑动的窗口。
窗口分成两部分:
第一部分是历史窗口(historywindow),存放最近被编码的一段正文;另一部分是向前看窗口(lookaheadwindow),存放从输入文件中读入,还没编码但正准备编码的一段正文。
历史窗口和向前看窗口都跟随压缩进程滑动,历史窗口作为术语字典,向前看窗口中待压缩的字符串如果在该历史窗口中出现,则输出其出现位置和长度。
窗口如下图所示:
|History|lookahead
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx