当前位置:文档之家› 数据压缩,算法的综述

数据压缩,算法的综述

数据压缩算法的综述S1******* 许申益摘要:数据压缩技术在数据通讯和数据存储应用中都有十分显著的益处。

随着数据传输技术和计算机网络通讯技术的普及应用,以及在计算机应用中,应用软件的规模和处理的数据量的急剧增加,尤其是多媒体技术在计算机通讯领域中的出现,使数据压缩技术的研究越来越引起人们的注意。

本文综述了在数据压缩算法上一些已经取得的成果,其中包括算术编码、字典式压缩方法以及Huffman码及其改进。

关键字:数据压缩;数据存储;计算机通讯;多媒体技术1.引言数据压缩技术在数据通讯和数据存储应用中都有十分显著的益处。

在数据的存储和表示中常常存在一定的冗余度,一些研究者提出了不同的理论模型和编码技术降低了数据的冗余度。

Huffman 提出了一种基于统计模型的压缩方法,Ziv Jacob 提出了一种基于字典模型的压缩方法。

随着数据传输技术和计算机网络通讯技术的普及应用,以及在计算机应用中,应用软件的规模和处理的数据量的急剧增加,尤其是多媒体技术在计算机和通讯两个领域中的出现,使数据压缩技术的研究越来越引起人们的注意。

本文综述了在数据压缩算法上的一些已经取得的成果。

本文主要介绍了香农范诺编码以及哈弗曼算法的基本思想,运用其算法的基本思想设计了一个文件压缩器,用Java 语言内置的优先队列、对象序列化等功能实现了文件压缩器的压缩和解压功能。

2数据压缩算法的分类一般可以将数据压缩算法划分为静态的和动态的两类。

动态方法又是又叫做适应性(adaptive)方法,相应的,静态方法又叫做非适应性方法(non-adaptive)。

静态方法是压缩数据之前,对要压缩的数据经过预扫描,确定出信源数据的每个符号在编码后对应的码字(codeword)。

这样,信息集对码字集的映像在数据开始之前就已经固定下来了。

面动态方法则是在编码过程中,随着信源信息的输入,根据输入流的变化,不断动态地修改编码压缩。

这样就省去了为统计信源中的符号概率需要做的第一遍预扫描。

也不必向编码端传送编码所用的数据模式。

因而动态的数据压缩方法比静态的方法要优越得多。

3.数据压缩技术的理论基础文件压缩的基本思想是对字符设计长度不等的编码方案,对出现次数多的字符用尽可能短的编码表示,这样文件的总长度就会降低,实现文件压缩。

比如有字符串“ABACADA”,4个字符需要两个比特编码,假设A、B、C、D的编码分别是00、01、10 和11,则整个字符串可表示成00010010001100,总长度14个比特。

如果A、B、C、D的编码分别是0、10、110 和111,则字符串总长度为12 比特。

设计长短不等的编码方案时,必须满足一个字符的编码不能是另一个字符编码的前缀,以保证解码成字符的转换过程中不发生歧义,这种编码称为前缀编码。

4.数据压缩算法4.1 Huffman编码及其演变哈弗曼算法提出了一种编码方法,使得文本总长度最短。

其基本思想是利用字符的频率作为权重,以字符作为叶结点构造一颗最优二叉树(也称为哈弗曼树),使得带权路径长度WPL = W1L1 + … + WnLn 最小,其中Wi 表示第 i 个字符结点的权重,Li 表示第 i 个字符结点的路径长度。

哈弗曼算法流程如下:(1)每个字符创建一棵二叉树构成一个树集合F= {T1,T2,…Tn},其中二叉树Ti 的根结点为权重wi,左右子树为空。

(2)在树集 F 中选取两颗根结点权值最小的树作为左右子树构成一颗新的二叉树,根结点为左右子树根结点的权重之和。

(3)在树集 F 中删除这两颗树,把新得到的二叉树加入到 F 中。

(4)重复步骤 2 和 3,直到 F 中只有一棵树为止。

例如字符串“ABACADA”4 个字符A、B、C、D 的频率分别为4、1、1、1。

以字符频率为权重构造最优树。

利用最优二叉树,A、B、C、D 的编码分别是0、10、110 和111。

这种以字符频率为权重,构造一颗最优二叉树,使得带权路径长度最小的前缀编码方案称为哈弗曼编码。

哈弗曼算法保证了高频字符用短编码,低频字符用长编码,到达整体编码长度最短,从而实现文件压缩的目的。

哈弗曼编码方法:先按出现的概率大小排队,把两个最小的概率相加,作为新的概率和剩余的概率重新排队,再把最小的两个概率相加,再重新排队,直到最后变成1。

每次相加时都将“0”和“1”赋与相加的两个概率,读出时由该符号开始一直走到最后的”0”或者“1”,将路线上所遇到的“0”和“1”按最低位到最高位的顺序排好,就是该符号的霍夫曼编码。

低位高位用霍夫曼编码所得的平均码长为:Σ(码长×出现概率)上例为:0.2×2+0.19×2+0.18×3+0.17×3+0.15×3+0.1×4+0.01×4=2.72 bit 可以算出本例的信源熵为2.61bit,二者已经是很接近了。

4.2 香农-范诺编码方法:将符号从最大可能到最少可能排序,将排列好的信源符号分化为两大组,使两组的概率和近于相同,并各赋予一个二元码符号“0”和“1”。

只要组内有两个或两个以上符号,就以同样的方法重复以上分组,以此确定这些符号的连续编码数字。

依次下去,直至每一组只剩下一个信源符号为止。

香农-范诺编码算法步骤:(1)按照符号出现的概率减少的顺序将待编码的符号排成序列。

(2)将符号分成两组,使这两组符号概率和相等或几乎相等。

(3)将第一组赋值为0,第二组赋值为1。

(4)对每一组,重复步骤2的操作,直至每一组只剩下一个信源符号为止。

5.文件压缩器的设计与实现文件数据在机器内部以二进制形式存在,机器对二进制比特以字节为单位进行处理。

从机器处理层面上来说,对文件数据的压缩就是对字节码形式的数据进行压缩。

文件压缩器的一个设计思想就是对高频字节码用短编码,低频字节码用长编码,把文件的字节码变换成哈弗曼码,使文件长度变短(以哈弗曼方法为例)。

文件压缩器主要的功能是压缩和解压,分别设计压缩类和解压类实现压缩和解压功能。

还有辅助功能的类,如结点类设计、叶结点类设计,用来构建哈弗曼树。

为了方便压缩后的数据保存及解压,需要设计一个压缩结果类,用来保存压缩结果和哈弗曼码表,在解压过程中必须用压缩过程的哈弗曼码表才能做逆变换,把压缩数据还原成原来的数据。

5.1 结点类设计Node 类表示哈弗曼树的分支结点,类中成员变量包括结点类型、权重、左子结点和右子结点等记录结点的基本信息数据。

Node 类表述如下:public class Node{public static int NODE = 0;//结点public static int LEAF = 1; //叶结点public Node lChild; //左结点public Node rChild; //右结点public int weight; //权重public int nodeStyle; //结点类型public Node (int weight, Node lChild, Node rChild):}Leaf 类是Node 类的派生类,表示树的叶子结点,成员变量包括字节码及字节码的哈弗曼编码。

Leaf 类表述如下:public class Leaf extends Node{public byte byteCode;//字节码public String huffCode;//哈弗曼码public Leaf (byte byteCode,int weight);}5.2 压缩结果类设计CompressedResult 类,用来保存压缩后的数据,保存原文件名供解压之后用,此外还要保存哈弗曼码表,在解压过程从哈弗曼码转换到字节码,必须使用压缩过程中的哈弗曼码表。

CompressedResult 类描述如下:public class CompressedResult implements Serializable{public String [] hufCodes;//哈弗曼码表public byte [] comedData;//压缩数据public String originalfileName;//原文件名}在具体实现过程中,采用了Java 语言的对象序列化功能,使得保存压缩文件和加载压缩文件的过程变得简单,简化了实现过程。

5.3 压缩类设计Compress 类该类完成文件加载、统计字节频率、构建哈弗曼树、生成哈弗曼码和文件压缩等功能。

Compress 类描述如下:public class Compress{private int [] weights;//字节码频率private String [] huffCodes;//字节码的哈弗曼码表private byte [] inputData; //文件数据private String srcPath; //源文件路径private File destPath;//目标文件路径//压缩结果private CompressedResult comedResult;//哈弗曼树private PriorityQueue<Node> huffTree;public Compress () ;//初始化变量//压缩函数public void compressing (String srcPath) ;private void saveFile (File f ) ; //保存压缩文件//目标路径private File getDefaultDestPath (String srcPath) ;//加载源文件private void loadFile (String srcPath) ;private void calculateWeight () ;//统计字符频率private void builtHufftree () ;//构建哈弗曼树//生成哈弗曼编码private void HuffmanCoding (Node root,String huffcode) ;//生成压缩文件private void generateCompressedData () ;//字符串转换成数值private byte string2Digit (String strCode) ;//优先队列的比较器,按权重比较结点大小private class ComparatorByWeight implements Comparator<Node>; }函数builtHufftree () 完成哈弗曼的构建,算法采用第2节中算法。

具体实现中哈弗曼树用Java 语言内置的优先队列PriorityQueue 类实现,队列中元素按权重自动排序,需要提供一个按权重比较大小的比较器,实现代码如下:huffTree = new PriorityQueue <Node> ( 256,new ComparatorBy-Weight ()); 函数HuffmanCoding (Node root, String huffcode) 完成对字节码的哈弗曼编码,生成字节码映射到哈弗曼码表huffCodes,其中字节码是huffCodes 的索引。

相关主题