霍夫曼编码对英文文本的压缩和解压缩

上传人:lis****210 文档编号:210454011 上传时间:2023-05-17 格式:DOCX 页数:22 大小:26.54KB
收藏 版权申诉 举报 下载
霍夫曼编码对英文文本的压缩和解压缩_第1页
第1页 / 共22页
霍夫曼编码对英文文本的压缩和解压缩_第2页
第2页 / 共22页
霍夫曼编码对英文文本的压缩和解压缩_第3页
第3页 / 共22页
资源描述:

《霍夫曼编码对英文文本的压缩和解压缩》由会员分享,可在线阅读,更多相关《霍夫曼编码对英文文本的压缩和解压缩(22页珍藏版)》请在装配图网上搜索。

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(outputfile,wb);if(

3、ofp=NULL)printf(nt压缩文件失败!n );system(pause);return;flength=0;while(!feof(ifp)fread(&c,1,1,ifp);/字符重复出现频率+1/字符出现原文件长度+1/原文件长度用作求压缩率的分母headerc.count+; flength+;flength-;length1=flength;headerc.count-;for(i=0;i512;i+)if(headeri.count!=0)headeri.b=(unsigned char)i;/*将每个哈夫曼码值及其对应的ASCII码 存放在一维数组headeri中,且编

4、码表 中的下标和ASCII码满足顺序存放关系*/ elseheaderi.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 结点break;n=i;m=2*n-1;for(i=n;im;i+)min1=999999999;/预设的最大

5、权值 ,即结点出现的最大次数for(j=0;jheaderj.count)pt1=j;min1=headerj.count;continue;headeri.count=headerpt1.count;headerpt1.parent=i;headeri.lch=pt1;min1=999999999;continue;if(min1headerj.count)pt1=j;min1=headerj.count;continue;headeri.count+=headerpt1.count;headeri.rch=pt1;headerpt1.parent=i;/哈夫曼无重复前缀编码for(i=0;

6、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编码,此处语句为网络借鉴else/置右分支编码 1j=strlen(headeri.bits);memmove(headeri.bits+1,headeri.bits,j+1);headeri.bits0=1;fseek(ifp,0,SEEK_

7、SET);/从文件开始位置向前移动0 字节,即定位到文件开始位置fwrite(&flength,sizeof(int),1,ofp);/*用来将数据写入文件流中 ,参数flength指向欲写入的数据地址,总共写入的字符数以参数 size*int 来决定,返回实际写入的 int 数目*/fseek(ofp,8,SEEK_SET);buf0=0;/定义缓冲区,它的二进制表示 00000000f=0;pt1=&/*假设原文件第一个字符是A , 8位2进制为01000001 ,编码后为 0110 识别编码第一个0, 那么将其左移一位,同理 4 位都做完,应该是 00000110,由于字节中的 8 位并

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;elsec=c0)strcat(buf,00000000);for(i=0;i8;i+)if(bufi=1)c=(c1)|1;elsec=c1;fwrite(&c,1,1,ofp);pt1+;fseek(ofp,4,SEEK_SET);/最后不满八位的 buf

9、 处理/buf 后加八位 0/逐位输入八位前的二进制符/指针回到输出文件头部后面四位/pt1 统计了输出文件中的字符个fwrite(&pt1,sizeof(long),1,ofp);fseek(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);fwrite(&c,1,1,ofp);j=strlen(headeri.bits);

10、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;elsec=c1;strcpy(headeri.bits,headeri.bits+8);fwrite(&c,1,1,ofp);/以上与上面连接字符一段可相同理解length2=pt1-;div=(double)lengt

11、h1-(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;printf(t 请您输入需要解压缩的文件(如无路径则默认为桌面文件):);gets(filename)

12、;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;/读入文件长度 flength/读入 header 数组的存储地址/读入 header 数组中元素的个/读入 header 数组fread(&flength,sizeof(long),1,ifp);frea

13、d(&f,sizeof(long),1,ifp);fseek(ifp,f,SEEK_SET);fread(&n,sizeof(long),1,ifp);数for(i=0;i0)m=p/8+1;elsem=p/8;for(j=0;jf;l-)strcat(headeri.bits,0);strcat(headeri.bits,buf);headeri.bitsp=0;for(i=0;in;i+)/按 Huffman 编码从小到大排序for(j=i+1;jstrlen(headerj.bits)tmp=headeri;headeri=headerj; headerj=tmp;p=strlen(he

14、adern-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函数此处的作用同,break;strcpy(bx,bx+headeri.count);c=headeri.b;fwrite(&c,1,1,ofp);m+;if(m=

15、flength)是比较 bx 的相应位是否与 headeri.bits 相若前 headeri.count 均相同,则返回 0 */m 用来统计解压缩后文件的长度/检验是否与源文件长度匹配break;ii回2乙0丑Y酚図场阜謝藝儿乙二P I二PQ二P!Q;uyvp%J*u!d:()qDia6=D心:(乙-0)台斷羽程阳*却骡藝詡曲尿Muyd區簡卑愿Y阳田MOP(.umWBIO WBM3 閒丑口尿)HuydC.UMIW4M 918000603d 人日做斷翁咚 ueuj目r)H耐J*u!d引!屮/3 1UI()uieuu iuilun妙l(“u俭u俭i回士排$:蓟吕排刃搦耐Jjwydas|aC.UMUMi回目玮E5肖吕城5期刃搦耐“)*5d (qi6um|j 二二 uu)j!刑u尿血 u、d(djo)msopjl(dj!)msopjn);returnwhile(c!=0 & c!=1 & c!=2);if(c=1)compress();else if(c=2)uncompress();elseexit(0);0;/调用压缩子函数/调用解压缩子函数

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!