文本压缩算法是怎么压缩的?
1.目前主要的文本压缩算法
文本压缩是根据一定的方法对大量数据进行编码处理以达到信息压缩存储的过程,被压缩的数据应该能够通过解码恢复到以前的状态,而不会发生信息丢失的现象。
2.文本压缩的分类
3.算法描述
3.1.Huffman编码
1.原理简介
- huffman压缩是数据结构课程中的常见内容, 是典型的贪心算法与二叉树的应用.
- 压缩前, 以ascii文本为例, 每个字符如a,b…都采用等长的8位acii码进行编码.
- huffman压缩的核心思想就是改为不等长编码, 使得出现较多的字符用较短的编码表示, 从而达到文本压缩的效果.
为了能够顺利的解码, 需要确保任意一个字符的编码不是另一个字符的前缀. 否则如a编码01,b编码位010, 那么在解码的过程中会出现岐义 - 因此问题转化为二叉树的最小带权外部路径长度问题. 对于一个二叉树它的每个叶子对应一个字符具体编码,编码值由从根到叶子的路径决定,例如 可以假定向左代表0,向右代表1. 每个叶子有一个权重, 可以是对应字符出现的次数或者频度.
- 算法过程是贪心的, 开始集合是所有的叶子节点权重, 每次取出两个权重最小的节点, 合并为一个内部节点并将其放回集合中, 直到集合中只有一个节点, 根节点. 即建好了这棵最优的二叉树, 也即得到了所有字符的huffman编码.
2.Huffman编码的优/缺点:
优点:
- 也是huffman树的特性,任何一个编码绝不会是其他编码的前缀,这一点保证的编码译码的唯一性。它是一个简单而且实用的算法。
缺点:
- 对于一些过短的文件进行 huffman编码的意义不大,因为我们存储huffman树的信息就需要1024bytes的空间;
- 对较大的文件进行编码,频繁的磁盘读写访问会降低数据编码的速度。
- 对文件的两次扫描。压缩时必须要知道每一个压缩字符在文本中出现的概率,所以要对文件中存储的字符进行两边扫描,第一遍计算每个字符在啊文版中出现的次数,创建出huffman树,在将 Huffman树的信息保存起来,以便解压缩创建同样额huffman树进行解压;第二遍是将文件中对应的字符转换为huffman编码存储到压缩文件中去。
3.2算术编码
原理:
算术编码是基于统计的、无损数据压缩效率最高的方法。它是从全序列出发,采用递推式的连续编码,他不是将单个信源符号映射成码子,而是将整段要压缩的整个数据序列映射到一段实数半封闭范围内的某一段区间,其长度等于该序列的概率。
优点:它避开用一个特定码字代替字符的思想,不需要传送huffman表,即_fileInfo,(自己实现的huffman文件压缩并没有传递该表,我是将信息全部放入压缩问件中,解压缩时从压缩文案中读取信息还原该表。)避免了huffman编码中比特位必须取整的问题。
缺点:
- 很难在具有固定精度的计算机完成无限精度的算术操作;
- 高度复杂的计算不利于实际应用
- 也需要两次扫描源数据流。
3.3基于字典的LZ系列编码
字典算法是将文本中出现频率较高的字符组合做成一个对应的字符字符列表,并用特殊的代码来表示字符。基于LZ序列的编码包括:LZ77算法、LZSS算法、LZ78算法、LZW等集中基本算法。LZ77和LZW算法实现起来很困难。
LZSS它是字典模式使用自适应模式,基本思路是搜索目前待压缩串是否在以前出现过,如果出现过则利用前次出现的的位置和长度来代替现在的待压缩串,输出该字符的出现位置及长度,否则输出新的字符串,从而起到压缩的目的。
优点:
压缩算法的细节处理不同只能影响压缩率和压缩时间,对解压程序不会有影响
缺点:熟读问题,每次都需要向前索引到文件开头
3.4游程编码
通过统计带压缩数据中的重复字符、去出除文本中的冗余字符或字节中的冗余位从而达到减少数据文件中所占用的存储空间的目的。
当信源概率比较接近时,建议使用算术编码,因为huffman编码的结果趋于定长码,效率不高。