问一个lzma的问题
网上google到一段话,lzma则是在huffman编码的时候,不再是考虑全局的概率,而是引入Markov链,当前的字符为a,则下一个字符为b的概率为p。
以前学过霍夫曼,现在忘记些了。我记得霍夫曼是根据 字符 在字符串中出现的概率来区分表示。出现概率大的字符,会用比较短的编码表示,字符概率出现比较小的,则使用长编码表示。
首先弱弱的表示一下,本人算法和数学功底差很多。不敢去step by step lzma之类的算法代码。所以在这和大家讨论下。
有这么个问题:
1,huffman在数据压缩的时候,应该是强耦合的。那么在压缩算法进行时,岂不是要多次扫描整个数据流?不知道huffman在压缩时大概会怎么做?
2,lzma的这句话没看懂。他是不是对已经做好huffman压缩的数据,再次做一个简单的编码,编码为两种?一种是a,另一种是b?
求有研究的高人解释
[解决办法]
1,分两种情况,一是两次扫描,第一次做统计,第二次做压缩,这时huffman树要随数据流一起传到解压缩,才能正确解压缩,二是一次扫描,每压缩完一个字符就对树进行一次调整,这叫自适应,压缩时效率较低,但不用传huffman树
2 lzma与huffman无关,它用了另一种压缩算法,算术编码
[解决办法]
(1)关于huffman的问题:
可以一次扫描也可以多次扫描吧
比如说你可以根据实际经验对字符进行编码就可以啦,也可以根据具体要压缩的数据进行分析然后编码
显然,前面的方法较快但压缩比率较低;而后一个方法较慢但压缩比率较高
简单的做法,统计这段数据中各个字符出现的次数,然后建立huffman树(这个过程就不说了,因为网上肯定能找到很多资料)
(2)关于第二个问题
大概来讲,关于压缩的定义概念可以分成三个层次
(a.1)基础算法,如huffman,算术编码,lz77等
这里面的每一个算法都可以对数据做压缩,但是他们的原理可能不同,因此适用性也不一样
如huffman是根据字符频率,降低经常出现的字符的编码长度来实现压缩的
lz77则是将前面出现过的长字符串缩短来实现压缩.
比如说abcdeabcdf,后一个abcd实际你不需要4个字节,只要(5,4)表示他和往前偏移5个字节,长度为4的字符串一样就可以了
仔细体会一下,这两者完全是不一样的思想.
(a.2)数据变化,如block sort等
这个是指可能在压缩前先对数据做一些变换,使得有较好特性,再进行压缩.
比如可以将abacadaf先变成aaaabcdf再进行压缩
(b)压缩算法,如deflate,lzma,lzh,lzx,quantum等等
这个层次是一个比较成熟的压缩算法了,他可能采用了上面的(a.1)(a.2)中的多个做组合
上面说过,不同的压缩算法之间的思想不一样,因此他们之间是有可能互补的
经典的deflate算法就用了huffman,lz
lzma算法lz,算术编码用了,我印象中这里也用huffman,但不确定
bzip2算法,用了上面说的block sort,huffman,lz
rar29用了lz,huffman,ppm,算术编码.
(c)压缩格式,如tar,gzip,zip,rar,7z等
每种压缩各种内部可能也会内置多种压缩算法以供选择,比如zip最常用的是deflate,但还提供了其他的几种(这个我想不起名字了,其实很少会用到这些算法)
PS:5楼说的话是对的
那本书可以看看吧,因为专门讲压缩的书除了他好像基本没有,不过基本也是讲的泛泛的东西吧
如果真的想深入了解,只能看开源代码了