版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、Huffman编码对英文文本的压缩和解压缩中国地质大学计算机学院信息安全专业信息论实验报告#include <stdio.h> #include <string.h> #include <conio.h>struct head unsigned char b;/记录字符在数组中的位置long count;/字符出现频率(权值) long parent,lch,rch;/定义哈夫曼树指针变量char bits256;/定义存储哈夫曼编码的数组 header512,tmp;void compress() char filename255,outputfile25
2、5,buf512; unsigned char c; long n,m,i,j,f; /作计数或暂时存储数据用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(
3、"pause"); return; printf("t请您输入压缩后的文件名(如无路径则默认为桌面文件):"); gets(outputfile); ofp=fopen(outputfile,"wb"); if(ofp=NULL)printf("nt压缩文件失败!n "); system("pause"); return; flength=0; while(!feof(ifp)fread(&c,1,1,ifp); headerc.count+;/字符重复出现频率+1flength+;/字
4、符出现原文件长度+1flength-; length1=flength;/原文件长度用作求压缩率的分母headerc.count-; for(i=0;i<512;i+)if(headeri.count!=0) headeri.b=(unsigned char)i; /*将每个哈夫曼码值及其对应的ASCII码存放在一维数组headeri中,且编码表中的下标和ASCII码满足顺序存放关系*/else headeri.b=0; headeri.parent=-1;headeri.lch=headeri.rch=-1;/对结点进行初始化 for(i=0;i<256;i+)/按出现权值从大到
5、小排序for(j=i+1;j<256;j+)if(headeri.count<headerj.count)tmp=headeri;headeri=headerj; headerj=tmp; for(i=0;i<256;i+)/找到第一个空的header结点if(headeri.count=0) break; n=i; m=2*n-1;for(i=n;i<m;i+)min1=999999999;/预设的最大权值,即结点出现的最大次数for(j=0;j<i;j+)if(headerj.parent!=-1) continue;/*parent!=-1说明该结点已存在哈
6、夫曼树中,跳出循环重新选择新结点*/if(min1>headerj.count)pt1=j; min1=headerj.count; continue; headeri.count=headerpt1.count; headerpt1.parent=i; headeri.lch=pt1; min1=999999999; for(j=0;j<i;j+)if(headerj.parent!=-1) continue;if(min1>headerj.count)pt1=j; min1=headerj.count; continue; headeri.count+=headerpt1
7、.count; headeri.rch=pt1; headerpt1.parent=i;/哈夫曼无重复前缀编码for(i=0;i<n;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);/依次存储连接"0""1"编码,此处语句为网络借鉴headeri.bits0=
8、39;0' else/置右分支编码1j=strlen(headeri.bits); memmove(headeri.bits+1,headeri.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
9、=0;/定义缓冲区,它的二进制表示00000000f=0; pt1=8;/*假设原文件第一个字符是"A",8位2进制为01000001,编码后为0110识别编码第一个'0',那么将其左移一位,看起来没什么变化。下一个是'1',应该|1,结果00000001 同理4位都做完,应该是00000110,由于字节中的8位并没有全部用完,继续读下一个字符,根据编码表继续拼完剩下4位,如果字符的编码不足4位,还要继续读一个字符,如果字符编码超过4位,那么把剩下的位信息拼接到一个新的字节里*/while(!feof(ifp)c=fgetc(ifp); f+
10、; for(i=0;i<n;i+)/找到对应的headeriif(c=headeri.b) break; strcat(buf,headeri.bits); j=strlen(buf);c=0; while(j>=8)for(i=0;i<8;i+)if(bufi='1') c=(c<<1)|1;/添加最后一位为1else c=c<<1;/添加最后一位为0fwrite(&c,1,1,ofp); pt1+; strcpy(buf,buf+8); j=strlen(buf);if(f=flength) break; if(j>0
11、)/最后不满八位的buf处理strcat(buf,"00000000");/buf后加八位0for(i=0;i<8;i+)/逐位输入八位前的二进制符if(bufi='1') c=(c<<1)|1; else c=c<<1; fwrite(&c,1,1,ofp); pt1+; fseek(ofp,4,SEEK_SET);/指针回到输出文件头部后面四位fwrite(&pt1,sizeof(long),1,ofp);/pt1统计了输出文件中的字符个数,包括了最后的'/0'fseek(ofp,pt1,SE
12、EK_SET); fwrite(&n,sizeof(long),1,ofp);/n统计了权值不为0的header数量for(i=0;i<n;i+)fwrite(&(headeri.b),1,1,ofp);/依次写入每个叶子结点的b、长度和内容c=strlen(headeri.bits); fwrite(&c,1,1,ofp); j=strlen(headeri.bits); if(j%8!=0)/若存储的位数不是8的倍数,则补0for(f=j%8;f<8;f+) strcat(headeri.bits,"0"); while(header
13、i.bits0!=0)/*字符的有效存储不超过8位,则对有效位数左移实现两字符编码的连接,可理解为前缀编码也被压缩过*/c=0; for(j=0;j<8;j+)if(headeri.bitsj='1')c=(c<<1)|1; else c=c<<1; strcpy(headeri.bits,headeri.bits+8); fwrite(&c,1,1,ofp);/以上与上面连接字符一段可相同理解 length2=pt1-;div=(double)length1-(double)length2)/(double)length1;/计算文件的压
14、缩率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; printf("t请您输入需要解压缩的文件(如无路径则默认为桌面文件):"); gets(filenam
15、e); 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(&
16、amp;flength,sizeof(long),1,ifp);/读入文件长度flengthfread(&f,sizeof(long),1,ifp);/读入header数组的存储地址fseek(ifp,f,SEEK_SET); fread(&n,sizeof(long),1,ifp);/读入header数组中元素的个数for(i=0;i<n;i+)/读入header数组fread(&headeri.b,1,1,ifp); fread(&c,1,1,ifp); p=(long)c; headeri.count=p; headeri.bits0=0; if(p
17、%8>0) m=p/8+1; else m=p/8; for(j=0;j<m;j+)fread(&c,1,1,ifp); f=c; itoa(f,buf,2);/*此处借鉴网络程序,包括itoa()函数 itoa()函数的作用为,把int型的f化为二进制数,再变成char型存入buf*/f=strlen(buf); for(l=8;l>f;l-)/在单字节内对相应位置补0strcat(headeri.bits,"0"); strcat(headeri.bits,buf); headeri.bitsp=0; for(i=0;i<n;i+)/按H
18、uffman编码从小到大排序for(j=i+1;j<n;j+)if(strlen(headeri.bits)>strlen(headerj.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)<(unsigned int)p)fread(&c,1,1,ifp); f=c; itoa(f,buf,2);f=strlen(
19、buf); for(l=8;l>f;l-)strcat(bx,"0"); strcat(bx,buf); for(i=0;i<n;i+)/依次比对Huffman前缀编码if(memcmp(headeri.bits,bx,headeri.count)=0)/*此函数也为网络借鉴,memcmp函数此处的作用是比较bx的相应位是否与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);
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年固原市五原中学招聘教师考试真题
- 2019年广东省广州市中考数学试卷-答案
- 2025-2026学年喀喇沁旗数学三年级下学期期中联考模拟试题(含答案)
- 2027年雅砻江职业学院高职单招职业适应性测试考试题库【预热题】附答案详解
- 2024年黑龙江佳木斯三江职业学院高职单招职业技能考试题库附参考答案详解(典型题)
- 2027年廊坊职业技术学院高职单招职业适应性测试考试模拟试卷及答案详解【历年真题】
- 2025年德州跃华职业学院单招综合素质考试模拟试卷【各地真题】附答案详解
- 2024年衡水技师学院桃城高职部单招职业技能考试题库(含答案详解)
- 2027年甘肃兰州黄河职业学院高职单招职业技能考试模拟试卷【学生专用】附答案详解
- 2024年河南大学民生学院专科单招综合素质考试题库及答案详解(有一套)
- GB/T 47652-2026温室气体产品碳足迹量化方法与要求光伏发电
- 2025年上海市青浦区社区工作者招聘笔试试题及答案详解
- 2026江苏苏州工业园区苏相合作区管理委员会机关人员招聘9人模拟试卷含答案详解(夺分金卷)
- 2026年四川省内江市“五方面人员”中选拔乡镇领导班子成员考试综合试题及答案
- 2026年注册安全工程师完整复习题库(附答案)
- 骨代谢疾病诊疗中国指南(2026 版)
- (期末复习)计算题 专项练习-2025-2026学年物理人教版 八年级下册
- 2026年首都机场招聘笔试试题及答案解析
- 中考英语感叹句综合练习100题(含答案)
- 电力公司发电厂运行维护人员考核表
- 护理按警示教育培训课件
评论
0/150
提交评论