实验报告格式样例.docx
- 文档编号:26516266
- 上传时间:2023-06-20
- 格式:DOCX
- 页数:15
- 大小:270.49KB
实验报告格式样例.docx
《实验报告格式样例.docx》由会员分享,可在线阅读,更多相关《实验报告格式样例.docx(15页珍藏版)》请在冰豆网上搜索。
实验报告格式样例
一、
二、
三、
四、实验题目:
哈夫曼编码实现文件压缩
五、实验目的:
1.了解文件的概念。
2.掌握线性链表的插入.删除等算法。
3.掌握Huffman的概念及构造方法。
4.掌握二叉树的存储结构及遍历算法。
5.利用Huffman树及Huffman编码,掌握实现文件压缩的一般原理。
三、实验设备与环境:
微型计算机·Windows系列的操作系统·VisualC++6.0软件
四、实验内容:
根据ascii码文件中各ascii字符出现的频率情况创建Huffman树,再将各字符对应的哈夫曼编码写入文件中,实现文件压缩。
五、概要设计:
此程序就是用MicrosoftVisualC++编写的。
根据ascii码文件中各ascii字符出现的频率情况创建Haffman树,再将各字符对应的哈夫曼编码写入文件中。
首先是对赫夫曼树进行定义,然后编写各个子函数,最后通过主函数对子函数的调用来实现程序的功能,其中用到了关于文本读入、挑选权值最小的字符、赫夫曼编码、建立赫夫曼树等的子函数。
通过读入的文本,对每个字符出现的次数进行统计,让后通过挑选函数,挑选权值最小的字符通过编码函数进行编码,然后把赫夫曼树的左右孩子分别赋值0、1;用这两个数字来表示各个字符,求出各个字符的二进制编码并把字符的二进制码存入文本中,便实现了压缩功能。
图见下页:
主要结构图如下:
读取输出
六、详细设计:
<1>赫夫曼树的结构体的定义,其中包括权值、父母、左右孩子及要编码的字符。
用这个结构体定义个赫夫曼数组。
定义如下:
structnode{
longweight;//权值
unsignedcharch;//字符
intparent,lchild,rchild;
charcode[256];//编码的位数最多为256位
intCodeLength;//编码长度
}hfmnode[512];
<2>读入文档,并计算其中出现的字符以及每个字符的权值,并统计文档中所有的字符个数:
printf("请输入要压缩的文件名:
");
scanf("%s",infile);
ifp=fopen(infile,"rb");
if(ifp==NULL)
{
printf("文件名输入错误,文件不存在!
\n");
return;
}
printf("请输入目标文件名:
");
scanf("%s",outfile);
ofp=fopen(outfile,"wb");
if(ofp==NULL)
{
printf("文件名输入错误,文件不存在!
\n");
return;
}
start1=clock();//开始计时1
//统计文件中字符的种类以及各类字符的个数
//先用字符的ASCII码值代替结点下标
FileLength=0;
while(!
feof(ifp))//用来统计读入的文件长度以及每个出现字符的权值
{
fread(&c,1,1,ifp);//一个流中读取数据
hfmnode[c].weight++;
FileLength++;
}
<3>初始化赫夫曼树,计算赫夫曼树的节点数,把左右孩子,双亲指针都定义成—1:
for(i=0;i<256;i++)
if(hfmnode[i].weight!
=0)
{
hfmnode[i].ch=(unsignedchar)i;
n++;//叶子数
hfmnode[i].lchild=hfmnode[i].rchild=hfmnode[i].parent=-1;
}
m=2*n-1;//哈弗曼树结点总数
j=0;
for(i=0;i<256;i++)//去掉权值为0的结点
if(hfmnode[i].weight!
=0)
{
hfmnode[j]=hfmnode[i];
j++;
}
for(i=n;i { hfmnode[i].lchild=hfmnode[i].rchild=-1; hfmnode[i].parent=-1; <4>写select()函数,用来挑选权值小的字符: intselect(structnode*nodep,intpose) { inti;ints1; longmin=2147483647;//s初值为long型的最大值 for(i=0;i<=pose;i++) { if(nodep[i].parent! =-1) continue; if(nodep[i].weight { min=nodep[i].weight; s1=i; } } returns1; } <5>建立赫夫曼树: for(i=n;i { s1=select(hfmnode,i-1); hfmnode[i].lchild=s1; hfmnode[s1].parent=i; s2=select(hfmnode,i-1); hfmnode[i].rchild=s2; hfmnode[s2].parent=i; hfmnode[i].weight=hfmnode[s1].weight+hfmnode[s2].weight; }//编码 <6>利用子函数encode(),对赫夫曼树进行编码,做孩子为0,右孩子为1: voidencode(structnode*nodep,intn) { //从叶子向根求每个字符的哈弗曼编码 intstart; inti,f,c; charcodes[256]; codes[n-1]='\0';//编码结束符 for(i=0;i { start=n-1; for(c=i,f=nodep[i].parent;f! =-1;c=f,f=nodep[f].parent) { start--; if(nodep[f].lchild==c) codes[start]='0'; elsecodes[start]='1'; } strcpy(nodep[i].code,&codes[start]); nodep[i].CodeLength=strlen(nodep[i].code); } } <7>将各个字符的二进制码存入文本,因为存储时按照8位一个字节进行的存储,对于不足8为的用0补足8位,然后进行存储: fseek(ifp,0,SEEK_SET);//将ifp指针移到文件开头位置 fwrite(&FileLength,4,1,ofp);//将FileLength写入目标文件的前4个字节的位置 fseek(ofp,8,SEEK_SET);//再将目标文件指针ofp移到距文件开头8个字节位置 codes[0]=0;//将编码信息写入目标文件 while(! feof(ifp)) { fread(&c,1,1,ifp); filelength++; for(i=0;i if(c==hfmnode[i].ch)break;//ch必须也为unsigned型 strcat(codes,hfmnode[i].code); while(strlen(codes)>=8) { for(i=0;i<8;i++)//将codes的前8位01代码表示的字符存入c { if(codes[i]=='1') c=(c<<1)|1; elsec=c<<1; } fwrite(&c,1,1,ofp);//将新的字符写入目标文件 sumlength++; strcpy(codes,codes+8);//更新codes的值 } if(filelength==FileLength)break; } //再将剩余的不足8位的01代码补全8位,继续写入 if(strlen(codes)>0) { strcat(codes,"00000000"); for(i=0;i<8;i++) { if(codes[i]=='1') c=(c<<1)|1; elsec=c<<1; } fwrite(&c,1,1,ofp); sumlength++; } for(i=0;i { fwrite(&(hfmnode[i].ch),1,1,ofp); c=hfmnode[i].CodeLength;//编码最长为256位,因此只需用一个字节存储 fwrite(&c,1,1,ofp);//写入字符的编码 if(hfmnode[i].CodeLength%8! =0) for(j=hfmnode[i].CodeLength%8;j<8;j++)//把编码不足8位的在低位补0,赋值给C,再把C写入 strcat(hfmnode[i].code,"0"); while(hfmnode[i].code[0]! =0)//开始存入编码,每8位二进制数存入一个字节 { c=0; for(j=0;j<8;j++) { if(hfmnode[i].code[j]=='1') c=(c<<1)|1; elsec=c<<1; } strcpy(hfmnode[i].code,hfmnode[i].code+8);//编码前移8位,继续存入编码 count++;//编码占的字节数的总值 fwrite(&c,1,1,ofp); } } printf("\n"); printf("源文件长度为: %ld个字节\n",FileLength); sumlength=sumlength+4+n*2+count;//计算压缩后文件的长度 printf("压缩后文件长度为: %ld个字节\n",sumlength); rate=(float)sumlength/(float)FileLength; printf("压缩率(百分比)为: %4.2f%%%\n",rate*100); fclose(ifp); fclose(ofp); return; 七、测试结果及分析: 试验结果: 首先运行程序,跳出菜单页面: 选择“压缩文件”,输入要压缩的文件,并且输入一个要将压缩后的文件存储的txt文档,会跳出选择是否查看压缩后的文件,选择“y”,进行查看: 从输出的结果上看,程序输出了每个叶子节点的权值,双亲,二进制编码,以及源文件长度和压缩后文件长度、压缩比等: 结果分析: 这个程序基本实现了对文本进行赫夫曼编码,但是存在一个缺陷,当文本不够长的时候,压缩后要比源文件还长,而利用大的文件进行压缩则会体现出他的优越性,如下面的试验结果: (1)编程过程中遇到的难题: (2)编程体会:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告 格式