哈夫曼实验报告材料附代码Word格式文档下载.docx

上传人:b****5 文档编号:17470565 上传时间:2022-12-01 格式:DOCX 页数:24 大小:36.79KB
下载 相关 举报
哈夫曼实验报告材料附代码Word格式文档下载.docx_第1页
第1页 / 共24页
哈夫曼实验报告材料附代码Word格式文档下载.docx_第2页
第2页 / 共24页
哈夫曼实验报告材料附代码Word格式文档下载.docx_第3页
第3页 / 共24页
哈夫曼实验报告材料附代码Word格式文档下载.docx_第4页
第4页 / 共24页
哈夫曼实验报告材料附代码Word格式文档下载.docx_第5页
第5页 / 共24页
点击查看更多>>
下载资源
资源描述

哈夫曼实验报告材料附代码Word格式文档下载.docx

《哈夫曼实验报告材料附代码Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《哈夫曼实验报告材料附代码Word格式文档下载.docx(24页珍藏版)》请在冰豆网上搜索。

哈夫曼实验报告材料附代码Word格式文档下载.docx

}HNodeType;

HNodeTypeHNode[2*N-1];

(2)编码的类型定义描述如下:

#defineMAXBIT10

typedefstruct

{intbit[MAXBIT];

intstart;

}HCodeType;

HCodeTypeHCode[N];

2.各模块伪算法

(1)主函数

intmain()

{

do:

{

界面友好设计;

cout<

<

各个选项功能内容;

cin>

>

ch;

容错处理;

switch(ch)

{

case1:

.....

}

}while();

return0;

}

(2)系统初始化模块

voidcreate()//系统初始化

for(i=0;

i<

2*N-1;

i++)//数组HNode初始化

{};

从键盘接收字符;

N;

i++)

{cout<

"

输入字符"

endl;

HNode[i].data;

}

接收权值;

构造哈夫曼树;

N-1;

{找最小和次小两个权值;

将找出的两棵子树合并为一棵子数;

将已建好的哈夫曼树存入文件hfmtree.txt中;

调用哈夫曼编码子函数;

voidHaffmanCode()//对哈夫曼树进行编码

从hfmtree.txt文件中读出哈夫曼树的信息存入内存HNodeTypea[2*N-1];

求每个叶子结点的哈夫曼编码;

从叶节点回溯,回溯到根结点(parent==-1);

记录回溯路径;

打印出每个字符对应的密文;

将密文信息存入文件codefile.dat中;

(3)编码模块

voidHfmanCode()//对用户输入的字符串进行编码

提示输入信息;

接收用户输入的要编译的字符串;

cin>

s;

//从文件中读取哈夫曼编码信息

infile.open("

F:

\\codefile.dat"

ios:

:

in|ios:

binary);

//读文件

i++)//将文件中的数据读出放在temp[i]内

//从文件中读字节到指定的存储器区域。

infile.read((char*)&

temp[i],sizeof(temp[i]));

循环实现将用户输入的字符串转换成对应的密文,并保存;

将保存结果存入密文文件;

voidtranslate()//译码

从文件hfmtree.txt中读出哈夫曼信息到内存temp[2*N-1];

从密文文件中读取用户输入的字符串的密文信息到内存c;

追溯结点位置初始定位到根结点temp[2*N-2];

c.num;

{

if(c.code[i]==0)

在当前结点的左子树下追溯叶子结点;

找到叶子结点则输出字符,当前结点重新定位到根结点;

else

在当前结点的右子树下追溯叶子结点;

输出并保存明文;

(4)译码模块

(5)输出模块

voidprint()//将哈夫曼树以凹入表的形式输出

从文件hfmtree.tet中读出哈夫曼树信息存入内存temp[2*N-1];

定义h=1;

调用递归输出函数print_t(temp,temp[2*N-2],h);

voidprint_t(HNodeTypetemp[],HNodeTypeT,inth)

{

//叶子结点输出字符,分支结点输出权值

if(T.data!

='

\0'

cout<

T.data<

else

T.weight<

递归调用左子树;

递归调用右子树;

 

五、调试分析

1.调试过程中遇到的问题和对问题的解决方法

对文件的读写操作不熟悉,调试时,将已写入的文件不能读出,以至于后续操作无法实现,对此,我有翻看C++程序设计课本,了解关于文件操作的具体内容,明白二进制文件和文本文件的读写方式是有很大区别的,不可混淆操作。

另外,对于程序的输出阶段开始时出现了问题,递归调用没有分析清楚,递归思想是层次分明,逐层深入。

2.算法的时间复杂度

(1)创建模块O(N^3)

(2)编码模块O(N)

(3)译码模块O(n)其中n为用户输入的密文位数

(4)打印模块O(N)

六、使用说明及测试结果

用户根据提示信息,初次使用本系统时要首先选择创建选项来初始化系统,根据提示信息输入信息,存入文件,使得后续功能顺利实现。

非初次使用时,用户可根据自己的需求来选择功能选项,根据提示信息输入、获得所需信息。

测试:

1.令叶子结点个数N为4,权值集合为{1,3,5,7},字符集合为{A,B,C,D},且字符集与权值集合一一对应。

2.令叶子结点个数N为7,权值集合为{12,6,8,18,3,20,2},字符集合为{A,B,C,D,E,F,G},且字符集与权值集合一一对应。

3.自行选定一段英文文本,统计给出的字符集,实际统计字符的频度,建立哈夫曼树,构造哈夫曼编码,并实现其编码和译码。

字符串:

whilwitchhiwwppppp频率统计为

w

h

i

l

c

t

p

4

3

1

5

4.可实现多个编码文件共存以及容错处理

七、程序代码

#include<

iostream.h>

iomanip.h>

fstream.h>

string.h>

#defineN7//叶子结点的个数

#defineMAXBIT50//编码位数

#defineMaxvalue100//定义最大权值整数常量

//结点的类型定义描述如下:

chardata;

intweight;

//编码类型描述如下:

chars;

//密文格式类型

intcode[MAXBIT];

intnum;

}CD;

voidcreate();

voidHaffmanCode();

voidprint();

voidprint_t(HNodeTypetemp[],HNodeTypeT,inth);

voidtranslate();

voidHfmanCode();

charname[50][30];

//用来记录用户输入的密文文件

intfilenum=0;

inttextnum=0;

intmain()

charch;

inth=1;

HNodeType*pNode;

pNode=HNode;

do{

setw(60)<

"

---------欢迎进入系统!

--------------"

setw(50)<

1:

初始化编译系统"

endl<

setw(40)<

2:

编码"

3:

译码"

setw(48)<

4:

打印哈弗曼树"

5:

退出"

--------------------------------------"

请选择(0~5):

;

while(!

(ch<

5'

&

ch>

0'

))/*输入不在0到5之间无效*/

cout<

数据输入错误,请重新选择(0~7):

cin>

switch(ch)

case'

1'

create();

break;

//系统初始化,构造哈夫曼树

2'

HfmanCode();

//对哈夫曼树进行编码

3'

translate();

//译码

4'

print();

//将哈夫曼树以凹入表的形式输出

case'

}while(ch!

);

voidcreate()//模块一,系统初始化

fstreamoutfile;

inti,j;

intm1,m2,x1,x2;

HNode[i].data='

HNode[i].weight=0;

HNode[i].parent=-1;

HNode[i].lchild=-1;

HNode[i].rchild=-1;

分别输入"

N<

个叶子结点的字符。

//从键盘接收叶子节点的权值

个与字符对应的权值。

输入权值"

HNode[i].weight;

i++)//构造哈夫曼树

m1=m2=Maxvalue;

x1=x2=0;

for(j=0;

j<

N+i;

j++)//找最小和次小两个权值

if(HNode[j].parent==-1&

HNode[j].weight<

m1)

{

m2=m1;

x2=x1;

m1=HNode[j].weight;

x1=j;

}

else

if(HNode[j].parent==-1&

m2)

{

m2=HNode[j].weight;

x2=j;

}

//将找出的两棵子树合并为一棵子数

HNode[x1].parent=N+i;

HNode[x2].parent=N+i;

HNode[N+i].weight=HNode[x1].weight+HNode[x2].weight;

HNode[N+i].lchild=x1;

HNode[N+i].rchild=x2;

outfile.open("

\\hfmtree.txt"

out|ios:

//建立进行写入的文件

if(!

outfile)//没有创建成功则显示相应信息

hfmtree.txt文件不能打开"

return;

//将内存中从HNode[i]地址开始的sizeof(HNode[i])的内容写入文件中

outfile.write((char*)&

HNode[i],sizeof(HNode[i]));

哈夫曼树信息已存入文件hfmtree.tet中."

outfile.close();

//关闭文件

HaffmanCode();

//调用函数对哈夫曼树进行编码

voidHaffmanCode()//对哈夫曼树进行编码

fstreamoutfile,infile;

inti,j,c,p;

HCodeTypecd;

HNodeTypea[2*N-1];

infile)

hfmtree.dat文件不能打开"

i++)//将文件中的数据读出放在a[i]内

//从文件中读字节到指定的存储器区域。

infile.read((char*)&

a[i],sizeof(a[i]));

infile.close();

//求每个叶子结点的哈夫曼编码

cd.start=N-1;

c=i;

p=a[c].parent;

while(p!

=-1)

if(a[p].lchild==c)

cd.bit[cd.start]=0;

cd.bit[cd.start]=1;

cd.start--;

c=p;

p=a[c].parent;

字符对应密文:

//打印出每个字符对应的密文

a[i].data<

---"

for(j=cd.start+1;

j++)

//保存求出的每个叶节点的哈夫曼编码和编码的起始位

HCode[i].bit[j]=cd.bit[j];

cd.bit[j];

HCode[i].start=cd.start;

HCode[i].s=a[i].data;

codefile.dat文件不能打开"

//将内存中从HCode[i]地址开始的sizeof(HCode[i])的内容写入文件中

outfile.write((char*)&

HCode[i],sizeof(HCode[i]));

//关闭文件n

密文信息已存入文件codefile.dat中."

inti,h=1;

HNodeTypetemp[2*N-1];

fstreaminfile;

print_t(temp,temp[2*N-2],h);

inti;

for(i=1;

h;

if(T.lchild==-1)

print_t(temp,temp[T.lchild],h+1);

//递归遍历左子树

print_t(temp,temp[T.rchild],h+1);

//递归遍历右子树

chars[50]={'

};

inti,j,k,n=0,m;

CDc;

c.num=0;

fstreaminfile,outfile;

HCodeTypetemp[N];

输入字符串"

m=strlen(s);

输入要将密文存放的文件名"

name[filenum];

filenum++;

m;

if(s[i]==temp[j].s)

for(k=temp[j].start+1;

k<

k++)

cout<

temp[j].bit[k];

//输出

c.code[c.num]=temp[j].bit[k];

//将字符对应密文存入c中

c.num++;

//记录密文长度

n++;

if(n==30)//实现每行输出30个密文

{

cout<

n=0;

}

outfile.open(name[filenum-1],ios:

name[filenum-1]<

.dat文件不能打开"

//将内存中从c内容写入文件中

c,sizeof(c));

密文信息已存入文件"

.dat中."

HNodeTypetemp[2*N-1],q;

charch,r[50]={'

},tempname[30]={'

intn=0,t=0,i;

输入要译码的文件"

tempname;

filenum;

if(strcmp(tempname,name[i])==0)

break;

if(i==filenum)

密文文件中没有"

tempname<

文件"

infile.open(name[i],ios:

cout

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

当前位置:首页 > 考试认证 > 从业资格考试

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

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