为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

英文文件的压缩和解压缩

2017-10-06 20页 doc 309KB 110阅读

用户头像

is_650122

暂无简介

举报
英文文件的压缩和解压缩英文文件的压缩和解压缩 合肥学院 计算机科学与技术系 课程设计报告 2009,2010学年第二学期 课程 数据结构与算法 课程设计名称 英文文件的压缩和解压缩 学生姓名 学号 专业班级 指导教师 李红 沈亦军 2010 年 6 月 题目:(采用哈夫曼编码思想实现文件的压缩和解压缩功能,并提供压缩前后的占用空间之比)(1)压缩原文件的规模应不小于5K。(2)提供解压缩后文件与原文件的相同性比较功能。 一、问题分析和任务定义。 1.1问题分析 本实验是利用哈夫曼编码思想,设计对一个文本文件中的字符进行哈夫...
英文文件的压缩和解压缩
英文文件的压缩和解压缩 合肥学院 计算机科学与技术系 课程 2009,2010学年第二学期 课程 数据结构与算法 课程设计名称 英文文件的压缩和解压缩 学生姓名 学号 专业班级 指导教师 李红 沈亦军 2010 年 6 月 题目:(采用哈夫曼编码思想实现文件的压缩和解压缩功能,并提供压缩前后的占用空间之比)(1)压缩原文件的规模应不小于5K。(2)提供解压缩后文件与原文件的相同性比较功能。 一、问题分析和任务定义。 1.1问题分析 本实验是利用哈夫曼编码思想,设计对一个文本文件中的字符进行哈夫曼编码,生成编码文件(压缩文件);反过来,可将一个压缩文件译码还原为一个文本文件(.txt)。要解决以上问题,需从以下几个方面着手: (1)如何读入待压缩的文本文件,统计文本文件中各字符的频数及出现的字符个数; (2)如何构造huffman树,进行huffman编码,生成压缩文件(后缀名.txt (3)如何读入待解压的压缩文件名,并利用相应的哈夫曼树及压缩文件中的二进制码将编码序列译码,对文件进行解压,生成解压文件(后缀名为.txt); (4)如何提供压缩前后的占用空间之比 1.2输入、输出数据的形式、值的范围,算法(程序)所能达到的功能 本实验的数据主要是以字符型为主,还有一些自定义的整形和浮点型变量,该实验室对文件进行压缩和解压(被压缩文件容量要求大于>5KB),通过该算法程序可以大致上满足实验所要求的功能,即压缩原文件的规模不小于5KB,提供了压缩后的文件与原文件的压缩比例,也即提供了性能比较功能 1.3 测试用的数据 本实验的数据是通过读入一个名为huffman.txt的文本文档,文档中为字符型数据。 所测试的部分数据: 图1.原文档 二、数据结构的选择和概要设计 为了完成实验所要求的任务,解决的问题及如下: 1.文件的读取及统计字符出现的个数和频率 (1)文件的读取 void read_file_count() {char c; ifstream infile; infile.open("huffman.txt");//打开huffman.txt文件 if(!infile)//检查文件是否打开。 {cout<<"不能打开 huffman.txt文件";//输出文件未打开的标志 exit(0);} cout<<"读入的文件中的内容为:"<方案
。 为了详细说明这个问题,特以下面例子来说明:有四个叶子结点A,B,C,D,分别 带权为9,4,5,2,可以构成许多种不同的带权二叉树,但各个带权二叉树的WPL(树 的带权路径长度)不同,要想由n个带权叶子结点所构成的二叉树中,满二叉树或完全 二叉树不一定是最优树。权值越大的结点离根越近的二叉树才是最优二叉树(huffman 树)。按照上面的算法,则可按照下面图的构造过程生成huffman树。 Huffman树产生流程:以一例说明 A B D C C A D B A A C C D B D B 图2.哈夫曼树产生流程 Huffman编码流程: int rem,p;int count1=0; count1=0; for(int y=1;y<=count;y++) rem=y;hcode[y].c=huff[y].data; p=huffman[y].parent; while(p!=0 ) if(huffman[p] .lchild==rem) hcode[y].bits[++count1]='1' ; hcode[y].bits[++count1]='0'; 图3.huffman编码流程 Huffman解码流程: fp1>>inchar; if(inchar=='1 ') ptr=huffman[ptr].rchildptr=huffman[ptr].lchild ; ; if(huffman[ptr].lchild== 0&&huffman[ptr].lchild ==0) fp2 图4.huffman解码流程 四、上机调试 开始考虑问题是,要对文件进行压缩,如何才能达到比较好的效果,那就是huffman编码是采用等长编码还是采用不等长问题,采用不等长编码要避免译码的二义性或多义性。假设用0表示字符D,用01表示字符C则当接受到编码串“„01„”,并译到字符0时,是立即译出对应的字符D,还是接着与下一个字符1一起译为对应的字符C,这就产生了二义性。因此,若对某一个字符集进行不等长编码,则要求字符集合中任一个字符的编码都不能是其他字符编码的前缀。符合此要求的编码叫做前缀编码。显然等长编码是前缀编码,这从等长编码所对应的编码二叉树也可以直接看出,任何一个叶子结点都不可能是其它叶子结点的双亲,也就是说,只有当一个结点是另一个结点的双亲时,该结点的字符编码才会是另一个结点的字符编码的前缀。 为了使不等长编码为前缀编码,可用该字符集中的每个字符作为叶子结点生成一棵编码二叉树,为了获得文件的最短长度,特将每个字符的出现频率作为字符结点的权值赋予该结点上,求出此树的最小带权路径长度就等于文件的最短长度。因此,对文件进行压缩,就可以转化字符集中的所有字符作为叶子结点,字符出现的频率作为权值所产生的huffman树的问题。 基本思路大致有了后,接下来是对程序的编写工作,程序初步形成后,对其测试,发现了一些变量还没有声明的错误,对遗漏的变量进行了声明后,再次调试,发现一个比较大的问题,就是字符都能读入,但是不能进行编码,也即不能构造 huffman树,最后经过检查发现原来是结点方面存在问题,最后加入sum=2*count-1;语句,问题得到解决。(该语句的作用是:例如提供了3个权值不同的结点,现在要构造huffman树,那就需要5个结点。) 五、测试结果 图5(与图6同为测试结果) 图6(与图5同为测试结果) 被编码(部分字符): 图7.被编码后的文档 被解码(部分文件): 图8.被解码后的文档 六、用户使用说明 用户运行本程序前,首先要在起工程文件下建立一个名字为Huffman.txt文本文档,再运行本程序后,第一步,按任意键来读取建立的 Huffman.txt文本文档,再据程序中提示完成第二步操作,也即是讲压缩的文件以Huffman编码放入一个由用户自己建立的文本文档中,接着再根据提示完成第三步操作,即对要压缩的文件解压后放入由用户建立的任意名的文本文档中,由此完成操作。 七、参考文献 [1] 王昆仑,李红. 数据结构与算法. 北京:中国铁道出版社,2006年5月。 [2] 郑莉等.c++语言程序设计(第三版)[M].北京:清华大学出版社,2003年12月 八、附录 #include #include #include #include using namespace std; string remfile[600000]; //存放原文件字符的数组 int remcount=0; //记录元素个数 float bitecount=0; //记录二进制码的个数 typedef struct { //存放读入字符的类 int count; //字符出现的个数 char data; //字符 }huffchar; int count=1; //记录huff数组中字符实际出现的个数 huffchar huff[1000]; //类的对象 //文件读入部分和统计字符出现的频率 bool char_judge(char c){ //判断字符出现的函数 for(int i=1;i<=count;i++) if(huff[i].data==c){ huff[i].count++; return true; } //如果出现过,出现的频数加1 return false; } void char_add(char c){ //添加新出现的字符; huff[count].data=c; huff[count++].count++; //个数增加 } //文件的读取 void read_file_count(){ char c; ifstream infile; infile.open("huffman.txt"); //打开huffman.txt文件 if(!infile){ //检查文件是否打开。 cout<<"不能打开 huffman.txt文件"; //输出文件未打开的标志 exit(0); } cout<<"读入的文件中的内容为:"<>str; fp.open(str.c_str()); if(!fp){ //检查文件是否打开 cout<<"不能打开 "<0;k--){ fp<>s1; fp2.open(s1.c_str()); if(!fp2){ //检查文件是否打开 cout<<"不能打开"<>inchar; if(inchar=='1') ptr=huffman[ptr].rchild;//查找相应编码对应huffman树中的位置 else ptr=huffman[ptr].lchild; if(huffman[ptr].lchild==0&&huffman[ptr].rchild==0){ //判断是否为叶子结点 fp2<
/
本文档为【英文文件的压缩和解压缩】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索