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