在LZ压缩算法的背后是使用RLE算法用先前出现的相同字节序列的引用来替代。
简单的讲,LZ算法被认为是字符串匹配的算法。例如:在一段文本中某字符串经常出现,并且可以通过前面文本中出现的字符串指针来表示。当然这个想法的前提是指针应该比字符串本身要短。
例如,在上一段短语“字符串”经常出现,可以将除第一个字符串之外的所有用第一个字符串引用来表示从而节省一些空间。
一个字符串引用通过下面的方式来表示:
1.唯一的标记
2.偏移数量
3.字符串长度
由编码的模式决定引用是一个固定的或变动的长度。后面的情况经常是首选,因为它允许编码器用引用的大小来交换字符串的大小(例如,如果字符串相当长,增加引用的长度可能是值得的)。
Lempel-Ziv压缩算法之实现
使用LZ77的一个问题是由于算法需要字符串匹配,对于每个输入流的单个字节,每个流中此字节前面的哪个字节都必须被作为字符串的开始从而尽可能的进行字符串匹配,这意味着算法非常慢。
另一个问题是为了最优化压缩而调整字符串引用的表示形式并不容易。例如,必须决定是否所有的引用和非压缩字节应该在压缩流中的字节边界发生。
基本压缩库使用一个清晰的实现来保证所有的符号和引用是字节对齐的,因此牺牲了压缩比率,并且字符串匹配程序并不是最优化的(没有缓存、历史缓冲区或提高速度的小技巧),这意味着程序非常慢。
另一方面,解压缩程序非常简单。
一个提高LZ77速度的试验已经进行了,这个试验中使用数组索引来加速字符串匹配的过程。然而,它还是比通常的压缩程序慢。
1.编码算法
LZ78的编码思想是不断地从字符流中提取新的缀-符串(String),通俗地理解为新“词条”,然后用“代号”也就是码字(Code word)表示这个“词条”。这样一来,对字符流的编码就变成了用码字(Code word)去替换字符流(Charstream),生成码字流(Codestream),从而达到压缩数据的目的。
在编码开始时词典是空的,不包含任何缀-符串(string)。在这种情况下编码器就输出一个表示空字符串的特殊码字(例如“0”)和字符流中 (Charstream)的第一个字符C,并把这个字符C添加到词典中作为一个由一个字符组成的缀-符串(string)。在编码过程中,如果出现类似的 情况,也照此办理。在词典中已经包含某些缀-符串(String)之后,如果“当前前缀P +当前字符C”已经在词典中,就用字符C来扩展这个前缀,这样的扩展 *** 作一直重复到获得一个在词典中没有的缀-符串(String)为止。此时就输出表示 当前前缀P的码字(Code word)和字符C,并把P+C添加到词典中作为前缀(Prefix),然后开始处理字符流(Charstream)中的下一个前缀。
LZ78编码器的输出是码字-字符(W,C)对,每次输出一对到码字流中,与码字W相对应的缀-符串(String)用字符C进行扩展生成新的缀-符串(String),然后添加到词典中。LZ78编码的具体算法如下:
步骤1: 在开始时,词典和当前前缀P都是空的。
步骤2: 当前字符C :=字符流中的下一个字符。
步骤3: 判断P+C是否在词典中:
(1) 如果“是”:用C扩展P,让P := P+C ;
(2) 如果“否”:
① 输出与当前前缀P相对应的码字和当前字符C;
② 把字符串P+C 添加到词典中。
③ 令P :=空值。
(3) 判断字符流中是否还有字符需要编码
① 如果“是”:返回到步骤2。
② 如果“否”:若当前前缀P不是空的,输出相应于当前前缀P的码字,然后结束编码。
2. 译码算法
在译码开始时译码词典是空的,它将在译码过程中从码字流中重构。每当从码字流中读入一对码字-字符(W,C)对时,码字就参考已经在词典中的缀-符串,然后把当前码字的缀-符串string.W 和字符C输出到字符流(Charstream),而把当前缀-符串(string.W+C)添加到词典中。在译码结束之后,重构的词典与编码时生成的词典完全相同。LZ78译码的具体算法如下:
步骤1: 在开始时词典是空的。
步骤2: 当前码字W :=码字流中的下一个码字。
步骤3: 当前字符C := 紧随码字之后的字符。
步骤4: 把当前码字的缀-符串(string.W)输出到字符流(Charstream),然后输出字符C。
步骤5: 把string.W+C添加到词典中。
步骤6: 判断码字流中是否还有码字要译
(1) 如果“是”,就返回到步骤2。
(2) 如果“否”,则结束。
[例4.6] 编码字符串如表4-13所示,编码过程如表4-14所示。现说明如下:
(1) “步骤”栏表示编码步骤。
(2) “位置”栏表示在输入数据中的当前位置。
(3) “词典”栏表示添加到词典中的缀-符串,缀-符串的索引等于“步骤”序号。
(4) “输出”栏以(当前码字W, 当前字符C)简化为(W, C)的形式输出。
表:编码字符串
位置 1 2 3 4 5 6 7 8 9
字符 A B B C B C A B A
表:编码过程
步骤 位置 词典 输出
1 1 A (0,A)
2 2 B (0,B)
3 3 BC (2,C)
4 5 BCA (3,A)
5 8 BA (2,A)
与LZ77相比,LZ78的最大优点是在每个编码步骤中减少了缀-符串(String)比较的数目,而压缩率与LZ77类似。
文件压缩原理我们使用计算机所做的事情大多都是对文件进行处理。每个文件都会占用一定的磁盘空间,我们希望一些文件,尤其是暂时不用但又比较重要不能删除的文件(如备份文件,有点像鸡肋呀),尽可能少的占用磁盘空间。但是,许多文件的存储格式是比较松散的,这样就浪费了一些宝贵的计算机存储资源。这时,我们可以借助压缩工具解决这个问题,通过对原来的文件进行压缩处理,使之用更少的磁盘空间保存起来,当需要使用时再进行解压缩 *** 作,这样就大大节省了磁盘空间。当你要拷贝许多小文件时,通过压缩处理可以提高执行效率。如果小文件很多, *** 作系统要执行频繁的文件定位 *** 作,需要花费很多的时间。如果先把这些小文件压缩,变成一个压缩文件后,再拷贝时就很方便了。由于计算机处理的信息是以二进制数的形式表示的,因此压缩软件就是把二进制信息中相同的字符串以特殊字符标记来达到压缩的目的。为了有助于理解文件压缩,请您在脑海里想象一幅蓝天白云的图片。对于成千上万单调重复的蓝色像点而言,与其一个一个定义“蓝、蓝、蓝……”长长的一串颜色,还不如告诉电脑:“从这个位置开始存储1117个蓝色像点”来得简洁,而且还能大大节约存储空间。这是一个非常简单的图像压缩的例子。其实,所有的计算机文件归根结底都是以“1”和“0”的形式存储的,和蓝色像点一样,只要通过合理的数学计算公式,文件的体积都能够被大大压缩以达到“数据无损稠密”的效果。总的来说,压缩可以分为有损和无损压缩两种。如果丢失个别的数据不会造成太大的影响,这时忽略它们是个好主意,这就是有损压缩。有损压缩广泛应用于动画、声音和图像文件中,典型的代表就是影碟文件格式mpeg、音乐文件格式mp3和图像文件格式jpg。但是更多情况下压缩数据必须准确无误,人们便设计出了无损压缩格式,比如常见的zip、rar等。压缩软件(compression software)自然就是利用压缩原理压缩数据的工具,压缩后所生成的文件称为压缩包(archive),体积只有原来的几分之一甚至更小。当然,压缩包已经是另一种文件格式了,如果你想使用其中的数据,首先得用压缩软件把数据还原,这个过程称作解压缩。常见的压缩软件有winzip、winrar等
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)