首页 > 其他分享 >学习霍夫曼编码

学习霍夫曼编码

时间:2023-07-13 15:12:30浏览次数:31  
标签:编码 char int 学习 pf av exit 霍夫曼

霍夫曼编码广泛用于数据压缩算法,其重要性不言而喻。

内容:写一个程序读ASCII文件,统计各字符的频率并制定霍夫曼编码表,最后将此文件的内容根据编码表翻译为二进制文件,计算压缩率。

代码清单:

#include...
typedef struct{
    float weight;
    int parent, lc, rc;
}node;
#define INIT_SLEN 512

int main(int ac, char **av){
    FILE *pf;
    unsigned int C[128], total, nz, slen, sz, cb;
    char *S, code[128][20];
    node T[256];
if(ac != 3){ printf("usage: %s <ascii-infile> <outfile>\n", av[0]); exit(1); } if(!(pf = fopen(av[1],"r"))){ perror("fopen"); exit(1); } memset(&C,0,sizeof C); total=0; for(int c; (c = fgetc(pf)) != EOF; ) C[c]++,total++;//计算各字符出现次数 fclose(pf); nz=0; memset(T,0,sizeof T); for(int i=0; i<128; i++){ if(C[i]) ++nz;//nz统计共有几种字符 T[i].weight=(float)C[i]/(float)total;/*计算该字符频度*/} for(int i=1, j=128; i<nz; i++){ int minP=-1, minQ=-1;//T[minP]的权重最小,minQ次小 for(int k=j-1; k>0; --k){ if(T[k].weight==0.0f || T[k].parent>0) continue; if(minP<0) minP=k; else if(minQ<0) minQ=k; else if(T[k].weight<T[minP].weight) minQ=minP, minP=k; else if(T[k].weight<T[minQ].weight) minQ=k; } //填充新霍夫曼树节点,权重是那俩的和,左右子树是那俩节点 T[j].weight=T[minP].weight + T[minQ].weight; T[j].lc=minP, T[j].rc=minQ; T[minP].parent=j, T[minQ].parent=j;
++j; } for(int i=0; i<128; i++){ if(C[i]==0){ code[i][0]='\0'; continue;} char tmp[32];//临时存放C[i]的编码 int pt=32; tmp[--pt]='\0'; for(int k=i, f=T[k].parent; k; k=f, f = T[f].parent) tmp[--pt]= (T[f].lc==k)? '0' : '1';//左分支编码0否则1 strcpy(&code[i][0], &tmp[pt]);/*复制到编码表code里*/} S=(char*)malloc(sizeof(char)*INIT_SLEN); if(!S){ perror("bad alloc"); exit(1); } slen=0, sz=INIT_SLEN; if(!(pf=fopen(av[1],"r"))){ perror("fopen"); exit(1); } for(int n, c; (c=fgetc(pf)) != EOF;){ n=strlen(code[c]);//该字符对应编码的长度 while(slen+n>=sz){//存不下就扩容 char *newS=realloc(S,sizeof(char)*2*sz); if(!newS){ free(S); perror("bad realloc"); exit(1); } S=newS; sz *= 2; } strcpy(S+slen,code[c]);//根据编码表翻译成01序列(ASCII形式) slen+=n; } fclose(pf); pf=fopen(av[2],"wb");//打开输出文件准备写二进制数据 if(!pf){ perror("bad out-file"); free(S); exit(1); } cb=0; for(int i=0; i<slen; i+=8){ int t = (i+8<=slen) ? 8: slen-i;//取长为t的零一序列 unsigned char b=0;//根据序列计算二进制码到b while(t>0){if(S[i]=='1') b |= 1<<(t-1); --t; } fputc(b,pf);/*写b并计数*/ ++cb; } free(S); fclose(pf); printf("old=%dB, new=%dB(%f%%)\n",total,cb,cb*100.0/total); }

到网上找一个文本文件,运行一下:新文件大小约是原文件的70%,只用这一招果然不太行。

标签:编码,char,int,学习,pf,av,exit,霍夫曼
From: https://www.cnblogs.com/tingzhouduruo/p/learn_huffman_code.html

相关文章

  • office学习笔记
    目录Excel函数使用VLOOKUP制作四象限图wordPowerPointExcel函数使用VLOOKUP使用说明:https://support.microsoft.com/zh-cn/office/vlookup-函数-0bbc8083-26fe-4963-8ab8-93a18ad188a1功能:需要在表格或区域中按行查找内容时,请使用VLOOKUP。说明:在这一最简单的形式中,VLOOK......
  • vim学习笔记
    指导文档https://cloud.tencent.com/developer/beta/article/2096379常用的命令1、行号::setnu#缩写,显示行号:setnumber#全写,显示行号:setnonu#缩写,取消显示行号:setnonumber#全写,取消显示行号2、删除:dd #删除一行echo"">x......
  • shell脚本学习笔记
    目录执行一个shell脚本变量赋值引用高级变量交互式shell数值计算test命令中括号判断符默认变量$0~$n$(())、$()、``、${}、''、""、()、(())、[]、[[]]、{}条件判断-与或非函数循环标准输入输出整数比较&字符串比较shell脚本中调用另一个shell脚本的三种方式:fork、exec、......
  • psql学习笔记
    目录Q:命令行执行文件里面的语句Q:docker本地运行psqlQ:常用命令Q:windows启动命令Q:统计数据库或表的磁盘空间占用Q:查询psql中的表结构信息Q:命令行执行文件里面的语句psql-Ugalax-W"wei***@123"-ddb_name-p5432-fxxx.sqlQ:docker本地运行psql1、获取最新的postg......
  • python学习笔记:第九章异常
    1.1异常是什么python使用异常对象来表示异常状态,并在遇到错误时引发异常。异常对象未被处理,程序将终止并显示一条错误信息。我们可以通过各种方法引发和捕获错误,并采取对应措施。1.2将“错误”变成异常自主地引发异常1.2.1raise语句我们通过预测异常可能发生的位置,通过ra......
  • Vue 学习 Day2
    摘要:动态属性的限制当使用DOM内嵌模板(直接写在HTML文件里的模板)时,我们需要避免在名称中使用大写字母,因为浏览器会强制将其转换为小写: <a:[someAttr]="value">...</a> “someAttr”属性而非“someattr”,这段代码将不会  ......
  • 关于学习的方法定律
    关于学习的方法定律定律1人们往往善于从事情的内容学习,而不善于从事情本身学习。公司的PLDP/PMDP培训效果很好,参加的人学到了如何做一个合格的PL/PM,却没有学会如何做好培训。从事情本身学习,是向别人学习的关键。定律2人们往往善于从失败中学习,而不善于从成功中学习。一件事......
  • 干货 | 深入理解深度学习中的激活函数
    理解深度学习中的激活函数在这个文章中,我们将会了解几种不同的激活函数,同时也会了解到哪个激活函数优于其他的激活函数,以及各个激活函数的优缺点。1.什么是激活函数?生物神经网络是人工神经网络的起源。然而,人工神经网络(ANNs)的工作机制与大脑的工作机制并不是十分的相似。不过在我......
  • 解决指定GPU运行和训练 python程序 、深度学习单卡、多卡 训练GPU设置【一文读懂】的
    指定GPU运行和训练Python程序,深度学习单卡、多卡训练GPU设置在进行深度学习任务时,GPU的使用是提高训练速度和效果的重要手段之一。在Python中,我们可以通过一些方法来指定GPU的运行和训练。指定GPU运行当我们使用多个GPU进行训练时,有时需要手动指定程序运行在哪个GPU上。这可以......
  • 强化学习Chapter2——优化目标(1)
    强化学习Chapter2——优化目标(1)上节涉及强化学习基本思路以及利用数学方式表征强化学习,但对强化学习的目标并没有进行详尽的定义。本节的目标旨在介绍algorithm-free的优化目标,即本文将不涉及算法地详述强化学习的目标。强化学习一般性目标上文提到,强化学习的目标可以解释为:......