




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
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教师资格试题含答案详解(综合题)
- 法院司法辅助人员题库试题(各地真题)附答案详解
- 危重患者交接班制度
- 2026届淮安市重点中学九年级英语第一学期期末学业水平测试试题含解析
- 用餐接待礼仪培训
- 中国政治制度讲解
- 2026届云南省腾冲市十五所学校英语九年级第一学期期末预测试题含解析
- 江苏省句容市华阳片区2026届九年级化学第一学期期中考试试题含解析
- 机关科室工作总结
- 教育学新闻汇报
- 颞下颌关节功能紊乱综合征的诊治
- 七年级上册英语单词形象记忆法
- 小学生科普知识蜜蜂介绍PPT
- 李建涛员工从“老板”做起课件
- GB/T 24346-2009纺织品防霉性能的评价
- FZ/T 12045-2014喷气涡流纺粘胶纤维色纺纱
- 船舶电气知识培训课件
- 苏轼生平课件
- 矿山爆破安全技术课件
- 中国文化概论-第6章-中国语言文字分解课件
- 水文学考试复习题和答案
评论
0/150
提交评论