1、实验报告 实验课名称:数据结构实验 实验名称:文件压缩问题 班级:20132012 学号: 姓名: 时间:2015-6-9 一、问题描述 哈夫曼编码就是一种常用得数据压缩技术,对数据文件进行哈夫曼编码可大大缩短文件得传输长度,提高信道利用率及传输效率.要求采用哈夫曼编码原理,统计文本文件中字符出现得词频,以词频作为权值,对文件进行哈夫曼编码以达到压缩文件得目得,再用哈夫曼编码进行译码解压缩。 二、数据结构设计 首先定义一个结构体: struct head { unsigned char b; //记录字符 long count;
2、 //权重 int parent,lch,rch; //定义双亲,左孩子,右孩子 char bits[256]; //存放哈夫曼编码得数组 } header[512],tmp; //头部一要定设置至少512个,因为结点最多可达256,所有结点数最多可达511 三、算法设计 输入要压缩得文件读文件并计算字符频率根据字符得频率,利用Huffman编码思想创建Huffman树由创建得Huffman树来决定字符对应得编码,进行文件得压缩解码压缩即根据Huffman树进行译码 设计流程图如图1、1所示. 建立哈夫曼树
3、 根据哈夫曼树解码 对二进制文件进行解码 统计字符,得出统计出字符得权值n 根据哈夫曼树编码 ﻩ 对编码进行压缩 生成哈夫曼树 生成对应文件 生成二进制文件 图1、1 设计流程图 (1)压缩文件 输入一个待压缩得文本文件名称(可带路径)如:D:\lu\lu、txt统计文本文件中各字符得个数作为权值,生成哈夫曼树;将文本文件利用哈夫曼树进行编码,生成压缩文件。压缩文件名称=文本文件名、COD 如:D:\lu\lu、COD压缩文件内容=哈夫曼树得核心内容+编码序列 for(int i=0;i<256;i++) { heade
4、r[i]、count=0; //初始化权重 header[i]、b=(unsigned char)i; //初始化字符 } ifstream in); while(in()!=EOF) { in((char *)&temp,sizeof(unsigned char)); //读入一个字符 header[temp]、count++; //统计对应结点字符权重 flength++; //统计文件长度 } in(); //关闭文件 for(i
5、0;i<256-1;i++) //对结点进行冒泡排序,权重大得放在上面,编码时效率高 for(int j=0;j<256-1-i;j++) if(header[j]、count〈header[j+1]、count) { tmp=header[j]; header[j]=header[j+1]; header[j+1]=tmp; } for(i=0;i<256;i++) if(header[i]、count==0) break; leafnum=i; //取得哈
6、夫曼树中叶子结点数
pointnum=2*leafnum—1; //取得哈夫曼树中总结点数目
in(in); //打开待压缩得文件
in();
in(0);
ofstream out); //打开压缩后将生成得文件
out((char *)&flength,sizeof(long)); //写入原文件长度
(2)哈夫曼编码
for(i=0;i 7、count=strlen(header[i]、bits); //不再设置其她变量,权值这时已无使用价值,可以用相应结点得权值变量记录长度
out((char *)&header[i]、count,sizeof(unsigned char)); //写入长度得ASCII码
if(header[i]、count%8==0)
bytelen=header[i]、count/8;
else
{
bytelen=header[i]、count/8+1;
strcat(header[i]、bits,”0000000”); 8、 //在编码后面补0,使其最后凑满8得倍数,
//超过无妨,可以用bytelen控制好写入字节得长度
}
for(int j=0;j 9、i<flength;i++)
{
cout< 10、缓冲区
{
in((char *)&temp,sizeof(temp));
ctoa(temp,code); //将字节转为数组
strcat(buf,code);
readlen++;
}//while
while(strlen(buf)〉=256) //处理缓冲区,直到少于256位,再读满它
{
for(i=0;i<strlen(buf);i++)
{
strcpy1(buf1,buf,i+1); //逐渐增多取,放入buf1 11、进行匹配
if(strcmp1(buf1,header,n,temp)==1)
{
out((char *)&temp,sizeof(unsigned char));
writelen++;
strcpy(buf,buf+i+1); //缓冲区前移
break;
}
}//for
if(writelen〉=flength) break; //如果写入达到原文件长度,退出
}//while
if(r 12、eadlen>=(clength-8)/*编码长度*/||writelen>=flength) break; //如果写入或者读入编码完毕,退出
}//退出此循环后,还有未解码完成得buf[]
//对buf[]缓冲得善后处理
while(writelen〈flength)
{
for(i=0;i 13、d char));
writelen++;
strcpy(buf,buf+i+1);
break;
}
}//for
}
in(); //关闭文件
out();
四、界面设计
程序包含压缩功能,解压功能,输出功能,帮助,终止程序功能。
五、运行测试与分析
(1)运行程序,显示提示,如图1、2所示。
图1、2 启动界面
(2) 编码操作.
图1、3在D盘中建立一个文本文档, 14、并命名为123、txt
图1、4文件压缩,输出哈弗曼编码界面
图1、5在D盘中生成一个。COD得文档,并且名为12、COD:
(3)解码操作。根据实验要求输出实验结果。如图1、4所示。
图1、4 数据结果输出界面
(4) 显示数据内容
若用户想知道文本输入得内容,可输入“L”, 然后界面提示输入文本文件得路径与文件名,完成输入后按回车键,界面会出现文本得内容。
六、实验收获与思考
在完成实验得过程中,使我明白了面向对象与面向对象得差别.在面向对象过程中,类得设计就是至关重要得,类设计好了等于程序就成功了一半,所以这次得课程帮助我复习了这一学期面向对象课程得学习,刚好可以弥补这一学期面向对象学习得不足。同时,也使我对数据结构与算法得知识有了一定得了解,帮我在大二学习数据结构与算法得课程中奠定了一定得基础,使我以后学习数据结构与算法得时候可以更加轻松.
教师评分:
教师签字:






