版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Huffman编码对英文文本的压缩和解压缩中国地质大学计算机学院信息安全专业信息论实验报告#include #include #include struct head unsigned char b;/记录字符在数组中的位置long count;/字符出现频率(权值) long parent,lch,rch;/定义哈夫曼树指针变量char bits256;/定义存储哈夫曼编码的数组 header512,tmp;void compress() char filename255,outputfile255,buf512; unsigned char c; long n,m,i,j,f; /作计数或
2、暂时存储数据用long min1,pt1,flength=0,length1,length2; /记录最小结点、文件长度double div;/计算压缩比用FILE *ifp,*ofp; /分别为输入、输出文件指针printf(t请您输入需要压缩的文件(需要路径):); gets(filename); ifp=fopen(filename,rb); if(ifp=NULL)printf(nt文件打开失败!n ); system(pause); return; printf(t请您输入压缩后的文件名(如无路径则默认为桌面文件):); gets(outputfile); ofp=fopen(out
3、putfile,wb); if(ofp=NULL)printf(nt压缩文件失败!n ); system(pause); return; flength=0; while(!feof(ifp)fread(&c,1,1,ifp); headerc.count+;/字符重复出现频率+1flength+;/字符出现原文件长度+1flength-; length1=flength;/原文件长度用作求压缩率的分母headerc.count-; for(i=0;i512;i+)if(headeri.count!=0) headeri.b=(unsigned char)i; /*将每个哈夫曼码值及其对应的A
4、SCII码存放在一维数组headeri中,且编码表中的下标和ASCII码满足顺序存放关系*/else headeri.b=0; headeri.parent=-1;headeri.lch=headeri.rch=-1;/对结点进行初始化 for(i=0;i256;i+)/按出现权值从大到小排序for(j=i+1;j256;j+)if(headeri.countheaderj.count)tmp=headeri;headeri=headerj; headerj=tmp; for(i=0;i256;i+)/找到第一个空的header结点if(headeri.count=0) break; n=i;
5、 m=2*n-1;for(i=n;im;i+)min1=;/预设的最大权值,即结点出现的最大次数for(j=0;jheaderj.count)pt1=j; min1=headerj.count; continue; headeri.count=headerpt1.count; headerpt1.parent=i; headeri.lch=pt1; min1=; for(j=0;jheaderj.count)pt1=j; min1=headerj.count; continue; headeri.count+=headerpt1.count; headeri.rch=pt1; headerpt
6、1.parent=i;/哈夫曼无重复前缀编码for(i=0;in;i+)f=i; headeri.bits0=0;/根结点编码0while(headerf.parent!=-1)j=f; f=headerf.parent; if(headerf.lch=j)/置左分支编码0j=strlen(headeri.bits); memmove(headeri.bits+1,headeri.bits,j+1);/依次存储连接01编码,此处语句为网络借鉴headeri.bits0=0; else/置右分支编码1j=strlen(headeri.bits); memmove(headeri.bits+1,h
7、eaderi.bits,j+1); headeri.bits0=1; fseek(ifp,0,SEEK_SET);/从文件开始位置向前移动0字节,即定位到文件开始位置fwrite(&flength,sizeof(int),1,ofp);/*用来将数据写入文件流中,参数flength指向欲写入的数据地址,总共写入的字符数以参数size*int来决定,返回实际写入的int数目*/ fseek(ofp,8,SEEK_SET); buf0=0;/定义缓冲区,它的二进制表示f=0; pt1=8;/*假设原文件第一个字符是A,8位2进制为,编码后为0110识别编码第一个0,那么将其左移一位,看起来没什么变
8、化。下一个是1,应该|1,结果 同理4位都做完,应该是,由于字节中的8位并没有全部用完,继续读下一个字符,根据编码表继续拼完剩下4位,如果字符的编码不足4位,还要继续读一个字符,如果字符编码超过4位,那么把剩下的位信息拼接到一个新的字节里*/while(!feof(ifp)c=fgetc(ifp); f+; for(i=0;i=8)for(i=0;i8;i+)if(bufi=1) c=(c1)|1;/添加最后一位为1else c=c0)/最后不满八位的buf处理strcat(buf,);/buf后加八位0for(i=0;i8;i+)/逐位输入八位前的二进制符if(bufi=1) c=(c1)|
9、1; else c=c1; fwrite(&c,1,1,ofp); pt1+; fseek(ofp,4,SEEK_SET);/指针回到输出文件头部后面四位fwrite(&pt1,sizeof(long),1,ofp);/pt1统计了输出文件中的字符个数,包括了最后的/0fseek(ofp,pt1,SEEK_SET); fwrite(&n,sizeof(long),1,ofp);/n统计了权值不为0的header数量for(i=0;in;i+)fwrite(&(headeri.b),1,1,ofp);/依次写入每个叶子结点的b、长度和内容c=strlen(headeri.bits); fwrit
10、e(&c,1,1,ofp); j=strlen(headeri.bits); if(j%8!=0)/若存储的位数不是8的倍数,则补0for(f=j%8;f8;f+) strcat(headeri.bits,0); while(headeri.bits0!=0)/*字符的有效存储不超过8位,则对有效位数左移实现两字符编码的连接,可理解为前缀编码也被压缩过*/c=0; for(j=0;j8;j+)if(headeri.bitsj=1)c=(c1)|1; else c=c1; strcpy(headeri.bits,headeri.bits+8); fwrite(&c,1,1,ofp);/以上与上面
11、连接字符一段可相同理解 length2=pt1-;div=(double)length1-(double)length2)/(double)length1;/计算文件的压缩率fclose(ifp); fclose(ofp); printf(nt压缩文件成功!n); printf(t压缩率为 %f%nn,div*100); return; void uncompress()char filename255,outputfile255,buf255,bx255; unsigned char c; long i,j,m,n,f,p,l; long flength; FILE *ifp,*ofp; p
12、rintf(t请您输入需要解压缩的文件(如无路径则默认为桌面文件):); gets(filename); ifp=fopen(filename,rb); if(ifp=NULL)printf(nt文件打开失败!n ); system(pause); return; printf(t请您输入解压缩后的文件名:); gets(outputfile); ofp=fopen(outputfile,wb); if(ofp=NULL)printf(nt解压缩文件失败!n ); system(pause); return; fread(&flength,sizeof(long),1,ifp);/读入文件长度
13、flengthfread(&f,sizeof(long),1,ifp);/读入header数组的存储地址fseek(ifp,f,SEEK_SET); fread(&n,sizeof(long),1,ifp);/读入header数组中元素的个数for(i=0;i0) m=p/8+1; else m=p/8; for(j=0;jf;l-)/在单字节内对相应位置补0strcat(headeri.bits,0); strcat(headeri.bits,buf); headeri.bitsp=0; for(i=0;in;i+)/按Huffman编码从小到大排序for(j=i+1;jstrlen(hea
14、derj.bits)tmp=headeri; headeri=headerj; headerj=tmp; p=strlen(headern-1.bits); fseek(ifp,8,SEEK_SET); m=0; bx0=0; while(1)/对文件其余部分,即真正的文件部分解压缩while(strlen(bx)f;l-)strcat(bx,0); strcat(bx,buf); for(i=0;in;i+)/依次比对Huffman前缀编码if(memcmp(headeri.bits,bx,headeri.count)=0)/*此函数也为网络借鉴,memcmp函数此处的作用是比较bx的相应位
15、是否与headeri.bits相同,若前headeri.count均相同,则返回0 */break; strcpy(bx,bx+headeri.count); c=headeri.b; fwrite(&c,1,1,ofp);m+;/m用来统计解压缩后文件的长度if(m=flength)/检验是否与源文件长度匹配break; fclose(ifp); fclose(ofp); printf(nt解压缩文件成功!n); if(m=flength) printf(t解压缩文件与原文件相同!nn); else printf(t解压缩文件与原文件不同!nn);return; int main()int c; while(1)printf(tHuffman前缀编码 压缩解压缩 BY PB 俞映洲n);printf(t1.压缩 2.解压缩 0.
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 银行做联动营销方案(3篇)
- 隧道混凝土支护施工方案(3篇)
- 医学26年:肺泡蛋白沉积症诊疗 查房课件
- 2026高血压性脑出血(HICH)重症管理专家共识
- 川北医学院就业指导
- 个人信息保护合规管理员常识能力考核试卷含答案
- 工艺品雕刻工诚信道德模拟考核试卷含答案
- 网络安全咨询员安全技能测试模拟考核试卷含答案
- 凹版印刷员岗前班组安全考核试卷含答案
- 柠檬酸充填封装工达标竞赛考核试卷含答案
- 七年级下学期家长会课件
- 市政道路工程路基施工专项方案
- 社会工作师考试培训服务协议
- 2026贵州农商联合银行社会招聘20人备考题库含答案详解(达标题)
- 2026年学习教育查摆问题清单及整改措施台账(四个方面16条)
- 2026年康复科医生面试临床病例分析答题思路
- 20121218部文-铁路旅客票价表
- 2025年中国股权投资市场研究报告
- 投资项目尽职调查报告书范本
- 食品安全法授课课件
- 成人教育档案管理制度
评论
0/150
提交评论