实验5huffman编码.docx

上传人:b****2 文档编号:20102156 上传时间:2023-04-24 格式:DOCX 页数:22 大小:258.99KB
下载 相关 举报
实验5huffman编码.docx_第1页
第1页 / 共22页
实验5huffman编码.docx_第2页
第2页 / 共22页
实验5huffman编码.docx_第3页
第3页 / 共22页
实验5huffman编码.docx_第4页
第4页 / 共22页
实验5huffman编码.docx_第5页
第5页 / 共22页
点击查看更多>>
下载资源
资源描述

实验5huffman编码.docx

《实验5huffman编码.docx》由会员分享,可在线阅读,更多相关《实验5huffman编码.docx(22页珍藏版)》请在冰豆网上搜索。

实验5huffman编码.docx

实验5huffman编码

深圳大学实验报告

课程名称:

算法设计与分析

实验项目名称:

Huffman编码

学院:

专业:

指导教师:

报告人:

学号:

班级:

实验时刻:

2017年11月26日

实验报告提交时刻:

2017年12月6日

教务部制

实验目的与要求:

一、实验目的:

(1)掌握Huffman编码。

(2)掌握文档压缩的基本原理和应用

二、分组:

一人一组

三、内容:

1.以字母(Character)为基础的压缩

1.文本解析:

将cacm.all文件分解成一个个的字母

2.字频统计:

统计每个字母出现的词频

3.Huffman编码:

根据Huffman编码的原理,对每个字母进行编码。

给出一个编码字典。

4.文档压缩:

根据Huffman编码,压缩文件。

5.文档还原:

对压缩后的文档进行解压缩。

2.比较

比较不同的压缩方法的效率

字母压缩

Rar压缩

时间效率

压缩效率

(选做)以字母压缩为基础的算法除了可以对文本文件进行压缩外,还可以对二进制文件进行压缩,比如对图像、视频、可执行文件的压缩。

自己找一些这类二进制文件,比较压缩算法对不同文件的压缩效率。

字母压缩

Rar压缩

BPM图像时间效率

BPM图像压缩效率

JPG图像时间效率

JPG图像压缩效率

EXE文件时间效率

EXE文件压缩效率

AVI文件时间效率

AVI文件压缩效率

RMBV文件时间效率

RMBV文件压缩效率

MPEG文件时间效率

MPEG文件压缩效率

MP3文件时间效率

MP3文件压缩效率

四:

提交内容

1.源程序

2.实验报告

3.压缩后的文档

4.词频统计表和Huffman编码表:

类似下面的表格(下表中的数据只是示例,以实际生成的数据为准)

字母

词频

Huffman编码(二进制)

a

1150000

00

b

980000

011

五.其他注意事项

以Huffman编码为基础的压缩文件应该以二进制的方式来存储,这就涉及到文件的读写操作中的“以文本方式打开文件”“以二进制方式打开文件”这两种不同的方式。

建议详细参考C语言中关于文件的读写这部分内容。

方法、步骤:

一.实验思路:

1.霍夫曼编码原理

假如给定字符串如下。

图一:

增广路径示意图

统计字符种类及每种字符出现的个数。

图二:

统计结果

每次选取权值最小的两个节点构建二叉树。

图三:

构建二叉树

置其根结点的权值为其左右子树权值之和。

图四:

构建设置父节点

删除表中两个已经添加过的叶子节点,将根节点置入表中,并回到第一步。

图五:

删除节点

注:

规定左节点小于右节点,当权值相等时比较字符在ASCII表中顺序。

图六:

构建霍夫曼表

重复上述步骤即可。

如果为二进制文件则用二进制打开并读取,每五位一组。

2.压缩率和压缩时间

字母压缩

Rar压缩

时间效率

259ms

0ms

压缩效率

62.2634%

25.84%

3.改进方法

问题:

要构造编码树必须提前统计符号出现概率,必须先进行扫描。

扫描要进行两次,第一遍统计符号出现概率,第二遍进行编码。

这里我们采用自适应的霍夫曼编码。

随着符号的统计也动态进行,同一个符号的编码可能发生改变。

霍夫曼编码方法不唯一。

因为编码时的0和1是任意给的,在两个符号有相同概率时的编码过程不唯一。

这些问题使解码需要编码树的结构,因此需要降低哈弗曼树的存储空间。

而范式霍夫曼编码则对于同一层的节点,所有的叶子节点都调整到左边。

然后,对于同一层的叶子节点按照符号顺序从小到大调整。

最后,按照左0右1的方案分配编码。

图七:

构建范式霍夫曼表

范式霍夫曼编码要求相同长度的码字是连续整数的二进制描述。

码字长度最小的第一个编码从0开始。

长度为i第一个码字f(i)必须满足f(i)=2(f(i-1)+1)。

例如,符号:

abcdefghijk...u,码长:

34444444455...5。

根据约定3,即first[3]=0可得到符号a的范式哈夫曼编码为000。

根据约定2,可得到first[4]=2*(first[3]+1)=2,进一步可知b的编码为0010。

由约定1可构造出符号c的编码为0011,由此类推可构造出整个码字空间。

在现实生活中,文章由单词构成,在单词重复率高或长篇幅文章中,按单词压缩效率会更高。

二.程序运行结果截图:

图八:

主程序运行窗口

图九:

文件压缩与解压缩及时间计算

图十:

实际生成的文件

其中:

●源程序:

main.cpp

●文本解析后的文件:

cacm.txt

●压缩后的文档:

encryption.txt

●词频统计表:

count.txt

●Huffman编码表:

code.txt

●解压缩后的文件:

decode.txt

图十一:

解析后的cacm.txt文件

图十二:

哈夫曼编码文件code.txt

图十三:

字频统计文件count.txt

图十三:

压缩后的文件encryption.txt

图十四:

解压缩后的文件deocde.txt

三.总结:

霍夫曼编码通过构建霍夫曼树缩短码长,从而实现对文件的压缩和解压。

四.实验心得

实验过程难免会遇到问题,掌握好的调试技巧能够快速查找出问题的所在,并通过排查,逐一改正程序中存在的问题,不管用什么编译器,都要学会设置适当的断点。

遇到不懂的地方要多查看相关的书籍或者在网上查找资料,这样才能真正学到东西。

实验结论:

霍夫曼编码通过构建霍夫曼树缩短码长,从而实现对文件的压缩和解压。

指导教师批阅意见:

成绩评定:

指导教师签字:

年月日

备注:

注:

1、报告内的项目或内容设置,可依如实际情形加以调整和补充。

2、教师批改学生实验报告时刻应在学生提交实验报告时刻后10日内。

 

附完整源码:

#include

#include

#include

#include

#include

usingnamespacestd;

constintmaxc=128;

typedeflonglongll;

charfilename[]="cacm.all";

llnum[maxc];

charcode[maxc][maxc];

chartemp[maxc];

structNode

{

boolisleaf;

charc;

lln;

Node*l,*r;

Node()

{

isleaf=false;

c=0;

n=0;

l=r=0;

}

}*o;

voidcount_char()

{

FILE*ffp=NULL;

FILE*fp=NULL;

charc;

//打开cacm.all文件

fp=fopen(filename,"r");

ffp=fopen("cacm.txt","w");

while(fread(&c,sizeof(c),1,fp))

{

num[(int)c]++;

fprintf(ffp,"%c",c);

}

fclose(fp);

fp=fopen("count.txt","w");

for(inti=0;i

fprintf(fp,"%d%c%lld\n",i,i,num[i]);

fclose(fp);

fclose(ffp);

}

structcmp

{

booloperator()(Node*a,Node*b)const

{

//因为优先出列判定为!

cmp,所以反向定义实现最小值优先

returna->n>b->n;

}

};

voidget_Huffman_tree()

{

priority_queue,cmp>q;

for(inti=0;i

{

Node*node=newNode();

node->isleaf=true;

node->c=i;

node->n=num[i];

q.push(node);

}

while(q.size()>1)

{

Node*x=q.top();

q.pop();

Node*y=q.top();

q.pop();

Node*z=newNode();

z->n=x->n+y->n;

z->l=x;

z->r=y;

q.push(z);

}

o=q.top();

q.pop();

}

voiddfs(Node*cur,intd)

{

if(cur->isleaf)

{

temp[d]=0;

strcpy(code[int(cur->c)],temp);

return;

}

temp[d]='0';

if(cur->l)dfs(cur->l,d+1);

temp[d]='1';

if(cur->r)dfs(cur->r,d+1);

}

voidget_Huffman_code()

{

dfs(o,0);

FILE*fp=NULL;

fp=fopen("code.txt","w");

for(inti=0;i

fprintf(fp,"%-3d%c%s\n",i,i,code[i]);

fclose(fp);

}

intcnt;

intnumber;

FILE*ffp=NULL;

voidadd(charc)

{

cnt++;

number<<=1;

number+=c-'0';

if(cnt==32)

{

cnt=0;

fwrite(&number,sizeof(number),1,ffp);

number=0;

}

}

voidflush()

{

while(cnt&&cnt<32)

{

cnt++;

number<<=1;

}

cnt=0;

fwrite(&number,sizeof(number),1,ffp);

number=0;

}

voidencryption()

{

ffp=fopen("encryption.txt","wb");

FILE*fp=NULL;

charc;

fp=fopen(filename,"r");

//while((c=fgetc(fp))!

=EOF)

while(fread(&c,sizeof(c),1,fp))

{

intlen=strlen(code[(int)c]);

for(inti=0;i

add(code[(int)c][i]);

}

flush();

fclose(fp);

fclose(ffp);

}

intNUM;

intCNT;

FILE*FFP=NULL;

intnextd()

{

if(CNT==0)

{

if(fread(&NUM,sizeof(NUM),1,FFP)==0)return2;

CNT=32;

}

CNT--;

return(NUM&(1<>CNT;

}

voiddecode()

{

FFP=fopen("encryption.txt","rb");

FILE*fp=NULL;

fp=fopen("decode.txt","w");

Node*cur=o;

intd;

while((d=nextd())<2)

{

if(d==0)cur=cur->l;

elsecur=cur->r;

if(cur->isleaf)

{

fprintf(fp,"%c",cur->c);

//printf("%c",cur->c);

cur=o;

}

}

fclose(fp);

fclose(FFP);

}

voidprintInfo()

{

cout<<"*****************************************"<

cout<<"**"<

cout<<"*文本压缩工具*"<

cout<<"*作者:

杨立滨*"<

cout<<"*源文件:

cacm.all*"<

cout<<"**"<

cout<<"*****************************************"<

}

intgetFileSize(char*file)

{

FILE*fp=NULL;

intnFileLen=0;

fp=fopen(file,"rb");

if(fp==NULL)

{

cout<<"can'topenfile"<

return0;

}

fseek(fp,0,SEEK_END);//定位到文件末

nFileLen=ftell(fp);//文件长度

returnnFileLen;

}

intmain()

{

printInfo();

cout<

count_char();

cout<

get_Huffman_tree();

get_Huffman_code();

cout<

doublestart=0,end=0;

start=clock();

encryption();//压缩

end=clock();

cout<<"压缩时间:

"<<(end-start)<<"ms"<

intsize1=getFileSize("cacm.txt");

intsize2=getFileSize("encryption.txt");

cout<<"cacm.txt文件大小:

"<

cout<<"encryption.txt文件大小:

"<

cout<<"压缩率:

"<<1.0*size2/size1*100<<"%"<

cout<

1:

是2:

否"<

inti;

cin>>i;

if(i==1){

cout<

decode();//解压缩

}

cout<<"程序结束!

"<

return0;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 其它模板

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1