winonafirst1
本篇将介绍 哈夫曼压缩算法(Huffman compression)
众所周知,计算机存储数据时,实际上存储的是一堆0和1(二进制)。
如果我们存储一段字符:ABRACADABRA!
那么计算机会把它们逐一翻译成二进制,如A:01000001;B: 01000010; !: 00001010.
每个字符占8个bits, 这一整段字符则至少占12*8=96 bits。
但如果我们用一些特殊的值来代表这些字符,如:
图中,0代表A; 1111代表B;等等。此时,存储这段字符只需30bits,比96bits小多了,达到了压缩的目的。
我们需要这么一个表格来把原数据翻译成特别的、占空间较少的数据。同时,我们也可以用这个表格,把特别的数据还原成原数据。
首先,为了避免翻译歧义,这个表格需满足一个条件: 任何一个字符用的值都不能是其它字符的前缀 。
我们举个反例:A: 0; B: 01;这里,A的值是B的值的前缀。如果压缩后的数据为01xxxxxx,x为0或者1,那么这个数据应该翻译成A1xxxxxx, 还是Bxxxxxxx?这样就会造成歧义。
然后,不同的表格会有不同的压缩效果,如:
这个表格的压缩效果更好。
那么我们如何找到 最好的表格 呢?这个我们稍后再讲。
为了方便阅读,这个表格是可以写成一棵树的:
这棵树的节点左边是0,右边是1。任何含有字符的节点都没有非空子节点。(即上文提及的前缀问题。)
这棵树是在压缩的过程中建成的,这个表格是在树形成后建成的。用这个表格,我们可以很简单地把一段字符变成压缩后的数据,如:
原数据:ABRACADABRA!
表格如上图。
令压缩后的数据为S;
第一个字符是A,根据表格,A:11,故S=11;
第二个字符是B,根据表格,B:00,故S=1100;
第三个字符是R,根据表格,R:011,故S=1100011;
如此类推,读完所有字符为止。
压缩搞定了,那解压呢?很简单,跟着这棵树读就行了:
压缩后的数据S=11000111101011100110001111101
记住,读到1时,往右走,读到0时,往左走。
令解压后的字符串为D;
从根节点出发,第一个数是1,往右走:
第二个数是1,往右走:
读到有字符的节点,返回此字符,加到字符串D里。D:A;
返回根节点,继续读。
第三个数是0,往左走:
第四个数是0,往左走:
读到有字符的节点,返回此字符,加到字符串D里。D:AB;
返回根节点,继续读。
第五个数是0,往左走:
第六个数是1,往右走:
第七个数是1,往右走:
读到有字符的节点,返回此字符,加到字符串D里。D:ABR;
返回根节点,继续读。
如此类推,直到读完所有压缩后的数据S为止。
压缩与解压都搞定了之后 我们需要先把原数据读一遍,并把每个字符出现的次数记录下来。如:
ABRACADABRA!中,A出现了5次;B出现了2次;C出现了1次;D出现了1次;R出现了2次;!出现了1次。
理论上,出现频率越高的字符,我们给它一个占用空间越小的值,这样,我们就可以有最佳的压缩率
由于哈夫曼压缩算法这块涉及内容较多 ,文章篇幅很长;全文全方面讲解了Compose布局的各方面知识。更多Android前言技术进阶,我自荐一套《 完整的Android的资料,以及一些视频课讲解 》 现在私信发送“进阶”或者“笔记”即可免费获取
最后我想说:
对于程序员来说,要学习的知识内容、技术有太多太多,要想不被环境淘汰就只有不断提升自己,从来都是我们去适应环境,而不是环境来适应我们
技术是无止境的,你需要对自己提交的每一行代码、使用的每一个工具负责,不断挖掘其底层原理,才能使自己的技术升华到更高的层面
Android 架构师之路还很漫长,与君共勉
Mr。。伍
手打的,你最好编译一下以免我哪里敲错了 (百度不能显示行首空格真是不爽) //哈夫曼树和~编码的存储表示 typedef struct{ unsigned int weight;//权值 unsigned int parent,lchild,rchild; }HTNode, *HuffmanTree;//动态分配数组存储哈夫曼树 typedef char * *HuffmanCode;//动态分配数组存储哈夫曼编码表 void HoffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){ //w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC if (n<=1) return; m=2*n-1; HT=(HuffmanTree) malloc ((m+1)*sizeof(HTNode));//0号单元未采用 for (p=HT,i=1;i<=n;++i,++p,++w) *p={*w,0,0,0}; for (;i<=m;++i;++p) *p={0,0,0,0} for (i=n+1;i<=m;++i){//建哈夫曼树 //在HT[1..i-1]选择parent为0且weight最小的两个结点编号分别为s1,s2 Select(HT,i-1,s1,s2); HT[s1].parent=i;HT[s2].parent=i; HT[i].lchild=s1;Ht[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //从叶子到根逆向求每个字符的哈夫曼编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n个字符编码的头指针向量 cd=(char *)malloc(n*sizeof(char));//分配求编码的工作空间 cd[n-1]="\0";//编码结束符 for (i=1;i<=n;++i){//逐个字符求哈夫曼编码 start=n-1;//编码结束符位置 for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)//从叶子逆向向根求编码 if (HT[f].lchild==c) cd[--start]="0"; else cd[--start]="1"; HC[i]=(char *)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC } free(cd);//释放工作空间 }//HuffmanCoding
廊坊电器城
typedef struct{ unsigned int weight;//权值 unsigned int parent,lchild,rchild; }HTNode, *HuffmanTree;//动态分配数组存储哈夫曼树 typedef char * *HuffmanCode;//动态分配数组存储哈夫曼编码表 void HoffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n){ //w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC if (n<=1) return; m=2*n-1; HT=(HuffmanTree) malloc ((m+1)*sizeof(HTNode));//0号单元未采用 for (p=HT,i=1;i<=n;++i,++p,++w) *p={*w,0,0,0}; for (;i<=m;++i;++p) *p={0,0,0,0} for (i=n+1;i<=m;++i){//建哈夫曼树 //在HT[1..i-1]选择parent为0且weight最小的两个结点编号分别为s1,s2 Select(HT,i-1,s1,s2); HT[s1].parent=i;HT[s2].parent=i; HT[i].lchild=s1;Ht[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } //从叶子到根逆向求每个字符的哈夫曼编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char *));//分配n个字符编码的头指针向量 cd=(char *)malloc(n*sizeof(char));//分配求编码的工作空间 cd[n-1]="\0";//编码结束符 for (i=1;i<=n;++i){//逐个字符求哈夫曼编码 start=n-1;//编码结束符位置 for (c=i,f=HT[i].parent;f!=0;c=f,f=HT[f].parent)//从叶子逆向向根求编码 if (HT[f].lchild==c) cd[--start]="0"; else cd[--start]="1"; HC[i]=(char *)malloc((n-start)*sizeof(char));//为第i个字符编码分配空间 strcpy(HC[i],&cd[start]);//从cd复制编码(串)到HC } free(cd);//释放工作空间 }//HuffmanCoding
《荒野生存》(乔恩•克拉考尔(Jon Krakauer))电子书网盘下载免费在线阅读 链接: 书名:荒野生存 作者:乔恩•克拉考尔(Jon Krakauer)
[1] 王军等.随机过程及其在金融领域中的应用[M].北京:清华大学出版社,交通大学出版社.2007.4.[2] 张大衡.马尔可夫链在企业经济预测上的应用
Lossless source coding is a kind of symbol when converting source code can be re
【中文摘要】随着信息社会和科学技术的发展,计算机在日常生活中起着越来越重要的作用。而算法是计算机工作的基础,了解算法知识及其思想成为现代社会每一个公民所应具备的
问题一:请提供几份毕业论文指导老师评阅意见(评语) wenku.baidu/...JRWfJW 问题二:毕业论文评阅老师评语 该生在毕业论文(设计