哈弗曼编码课程设计实验报告.docx
《哈弗曼编码课程设计实验报告.docx》由会员分享,可在线阅读,更多相关《哈弗曼编码课程设计实验报告.docx(30页珍藏版)》请在冰豆网上搜索。
![哈弗曼编码课程设计实验报告.docx](https://file1.bdocx.com/fileroot1/2023-2/4/74a89a40-f39c-4e2b-92eb-4c95bb03e526/74a89a40-f39c-4e2b-92eb-4c95bb03e5261.gif)
哈弗曼编码课程设计实验报告
一、实训要求……………………………………………………………………………..2
二、课题分析和设计……………………………………………………………………..2
1、基本需求分析……………………………………………………………………2,3
2、对应的类………………………………………………………………................3,4,5
三、主要功能界面………………………………………………………………………...5
1、主界面……………………………………………………………………………5
2、读取文章并对字符编码…………………………………………………………5
3、哈弗曼编码信息………………………………………………………………….6
4、文章编码………………………………………………………………………….6
5、文章译码………………………………………………………………………….6
6、错误处理………………………………………………………………………….7
四、总结(课设心得体会)………………………………………………………………7
五、附录(主要函数代码)………………………………………………………………7~14
一、实训要求
1、输入为:
一段中文或英文的文章的文件名。
2、读取文章的字符信息。
3、对字符进行权值的计算。
4、根据权值构造哈弗曼树。
5、生成对应的编码。
6、输出为:
原文章的编译(译文)。
7、根据已经生成的编码表,输入任意的译文可以得到原文。
二、课题分析和设计
1.基本需求分析:
(1)在通信过程中,为了提高信道利用率,缩短信息传输时间降低传输成本,需要一编译码器。
(2)此哈弗曼编码译码器应具有编码译码的双向功能,即在发送端通过编码系统对传入的数据进行编码。
(3)在接收端将数据译码,将具有两项功能的编码译码器用于双工信道就可满足,双工信道的双向编译功能。
(4)输入某段报文是,系统将自己完成编译输出。
(5)、程序设计流程:
<1>文字表述:
开始进入功能选择界面,包含五种操作
(1)读取文章并对字符编码。
(2)哈夫曼编码信息。
(3)文章编码。
(4)文章译码。
(5)退出程序。
<2>操作:
(1)给定一篇文章,统计字符出现的概率,并根据概率建立哈弗曼树,并利用哈弗曼树对字符进哈夫曼编码。
(2)显示哈弗曼编码信息,包括字符和其哈弗曼编码。
(3)对文章进行译码,显示译码信息,并保存。
(4)对文章进行译码,显示并保存。
<3>流程图:
2、对应的类:
<1>定义类:
classElement//结点类
{
public:
charname;//字符名
intweight;//字符权值
intlchild;//左孩子
intrchild;//右孩子
intparent;//父结点
Element()
{
weight=0;
lchild=-1;
rchild=-1;
parent=-1;
}
~Element(){}
};
<2>定义字符和出现的次数:
className//字符类
{
public:
charpname;//字符名
intnum;//字符出现的次数
doublelweight;//字符的权值
Name()
{
num=0;
lweight=0;
}
~Name(){}
};
<3>定义字符总类总数和存储信息:
classGetName//关于字符类
{
public:
charfile_name[max2];//文件名
intn;//字符的种类
intsum;//字符的总数
Nameletter[max1];//存储字符信息的类的数组
GetName()
{
sum=0;
n=0;
}
};
<4>定义编码类:
classCodeNode//编码类
{
public:
charch;//存储字符
charsave_code[max1];//存储编码
};
<5>主要功能实现类:
classFunction
{
public:
GetNameL;
intfn;//定义哈夫曼数组大小
ElementHuffmanT[max3];//哈夫曼数组
CodeNodeCode[max1];//字符编码数组
Function()
{
fn=0;
}
};
3、主要功能界面:
1、主界面:
2、?
取文章并?
字符?
?
:
3、哈弗曼?
?
信息:
4、文章?
?
:
5、文章?
?
:
6、?
?
?
理:
4、?
?
(?
?
心得体?
):
三周的?
程?
?
?
束了,在?
次的?
程?
?
中不?
?
?
了我所?
?
的知?
,也培?
了我如何去把握一件事情,如何去做一件事情,又如何完成一件事情。
在?
?
?
程中,与同?
分工?
?
,和同?
?
相互探?
,相互?
?
,相互?
督。
?
?
了合作,?
?
了?
?
帷幄,?
?
了?
容,?
?
了理解,也?
?
了做人与?
世。
?
程?
?
是我?
?
?
?
程知?
?
合?
用的?
?
?
?
,?
是我?
?
向社?
,?
事?
?
工作前一?
必不少的?
程.¡¨千里之行始于足下¡¨,通?
?
次?
程?
?
,我深深体?
到?
句千古名言的真正含?
.我今天?
真的?
行?
程?
?
,?
?
?
踏?
地?
?
?
一步,就是?
明天能?
健地在社?
大潮中奔跑打下?
?
的基?
.通?
?
次?
程?
?
,本人在多方面都有所提高。
在?
次?
?
?
程中,体?
出自己?
?
?
?
模具的能力以及?
合?
用知?
的能力,体?
了?
以致用、突出自己?
?
成果的喜?
心情,?
中?
?
自己平?
?
?
的不足和薄弱?
?
,?
而加以?
?
。
六、附?
(源代?
):
#include
#include
#include
#include
#definemax1150
#definemax250
#definemax3256
usingnamespacestd;
classElement//?
?
?
{
public:
charname;//字符名
intweight;//字符?
值
intlchild;//左孩子
intrchild;//右孩子
intparent;//父?
?
Element()
{
weight=0;
lchild=-1;
rchild=-1;
parent=-1;
}
~Element(){}
};
classCodeNode//?
?
?
{
public:
charch;//存?
字符
charsave_code[max1];//存?
?
?
};
className//字符?
{
public:
charpname;//字符名
intnum;//字符出?
的次?
doublelweight;//字符的?
值
Name()
{
num=0;
lweight=0;
}
~Name(){}
};
classGetName//?
于字符?
{
public:
charfile_name[max2];//文件名
intn;//字符的种?
intsum;//字符的?
?
Nameletter[max1];//存?
字符信息的?
的?
?
GetName()
{
sum=0;
n=0;
}
voidGetWeight()//得到字符的?
值
{
for(inti=0;i{
letter[i].lweight=(double)letter[i].num/sum;//出?
的次?
除?
?
得到?
值
}
}
intReadLetter()
{
ifstreaminput;
cout<<"?
?
入文件名:
"<cin>>file_name;
input.open(file_name);//打?
文件
if(input.fail())
{
cout<<"?
文件不存在!
"<return0;
}
charch;
ch=input.get();
letter[0].pname=ch;
letter[0].num++;
sum++;
while(!
input.eof())//?
取文件中的所有字符
{
inttag=0;
ch=input.get();
for(inti=0;i{
if(letter[i].pname==ch)
{
letter[i].num++;
sum++;
tag=1;
}
}
if(tag==0)
{
n++;
letter[n].pname=ch;
letter[n].num++;
sum++;
}
}
sum--;
input.close();
GetWeight();//得到字符?
值
}
};
classFunction
{
public:
GetNameL;
intfn;//定?
哈夫曼?
?
大小
ElementHuffmanT[max3];//哈夫曼?
?
CodeNodeCode[max1];//字符?
?
?
?
Function()
{
fn=0;
}
voidCharHuffmanTCoding()//?
?
功能?
?
{
inti,f,c;
char*cd=newchar[L.n+1];//?
?
存?
?
?
的?
?
intstart;//?
?
?
取起始位置
cd[L.n]='\0';
for(i=0;i{
Code[i].ch=HuffmanT[i].name;//字符信息
start=L.n;//起始位置
c=i;
while((f=HuffmanT[c].parent)>=0)
{
if(HuffmanT[f].lchild==c)//如果?
左孩子,?
‘0’
{
cd[--start]='0';
}
else//如果?
右孩子,?
‘1’
{
cd[--start]='1';
}
c=f;
}
strcpy(Code[i].save_code,&cd[start]);//?
?
果存入?
?
的?
?
?
?
中
}
}
voidOutputHuffmanTCode()
{
cout<<"哈夫曼?
?
:
"<cout<<"——————————————————————"<cout<<"字符\t\t哈夫曼?
?
"<for(inti=0;i出字符,哈夫曼?
?
{
cout<<"——————————————————————"<cout<cout<cout<}
cout<<"——————————————————————"<}
voidInitHT()//哈夫曼初始化
{
L.ReadLetter();
fn=(L.n)*2-1;
for(inti=0;i{
if(i{
HuffmanT[i].name=L.letter[i].pname;
HuffmanT[i].weight=L.letter[i].lweight;
}
}
}
voidSelect_2Min(intm,int&p1,int&p2)//?
?
最小的?
?
?
?
{
inti;
doublem1,m2;
m1=m2=1;
p1=p2=-1;
for(i=0;i{
if(HuffmanT[i].parent==-1&&HuffmanT[i].weight?
?
的?
值最小?
?
{
m2=m1;
p2=p1;
m1=HuffmanT[i].weight;
p1=i;
}
elseif(HuffmanT[i].parent==-1&&HuffmanT[i].weight?
?
的?
值第二小?
?
{
m2=HuffmanT[i].weight;
p2=i;
}
}
}
voidCreatHT()//建立哈夫曼?
//核心
{
inti,p1,p2;
InitHT();
for(i=L.n;i{
Select_2Min(i,p1,p2);
HuffmanT[p1].parent=HuffmanT[p2].parent=i;
HuffmanT[i].weight=HuffmanT[p1].weight+HuffmanT[p2].weight;
HuffmanT[i].lchild=p1;
HuffmanT[i].rchild=p2;
}
}
intOutArticleCode()//?
示文章?
?
{
ifstreaminput;
input.open(L.file_name);
if(input.fail())
{
cout<<"文件不存在!
"<return0;
}
charch;
cout<<"文章?
?
如下:
"<while(!
input.eof())
{
ch=input.get();
for(inti=0;i{
if(Code[i].ch==ch)
cout<}
}
cout<input.close();
}
intSaveArticleCode()//保存文章?
?
{
ofstreamoutput;
ifstreaminput;
charnamef1[max2];
input.open(L.file_name);
if(input.fail())
{
cout<<"?
文件不存在!
"<return0;
}
cout<<"?
?
入保存文章?
?
的文件名:
"<cin>>namef1;
output.open(namef1);
charch;
while(!
input.eof())
{
ch=input.get();
for(inti=0;i{
if(Code[i].ch==ch)
{
for(intj=0;j{
output.put(Code[i].save_code[j]);
}
}
}
}
input.close();
output.close();
cout<<"保存完?
!
"<}
intOutTransCode()//文章?
?
操作
{
ifstreaminput;
charnamef[max2];
cout<<"?
?
入保存文章?
?
的文件名:
"<cin>>namef;
input.open(namef);
if(input.fail())
{
cout<<"?
文件不存在!
"<return0;
}
charch;
ch=input.get();
intc=2*L.n-2;
while(!
input.eof())
{
if(ch=='0')//遇0搜索左子?
{
if(HuffmanT[c].lchild>=0){
c=HuffmanT[c].lchild;
}
if(HuffmanT[c].lchild==-1)//判?
是否到?
子
{
cout<出字符
c=2*L.n-2;//返回根?
?
}
}
if(ch=='1')//遇1搜索右子?
{
if(HuffmanT[c].rchild>=0)
{
c=HuffmanT[c].rchild;
}
if(HuffmanT[c].rchild==-1)//判?
是否到?
子
{
cout<出字符
c=2*L.n-2;//返回根?
?
}
}
ch=input.get();
}
cout<input.close();
}
intSaveTransCode()//保存文章?
?
{
ofstreamoutput;
ifstreaminput;
charnamef[max2];
charnamef1[max2];
cout<<"?
?
入文章?
?
所在的文件名:
"<cin>>namef;
input.open(namef);
if(input.fail())
{
cout<<"?
文件不存在!
"<return0;
}
cout<<"?
?
入保存文章?
?
的文件名:
"<cin>>namef1;
output.open(namef1);
charch;
ch=input.get();
intc=2*L.n-2;
while(!
input.eof())
{
if(ch=='0')
{
if(HuffmanT[c].lchild>=0)
{
c=HuffmanT[c].lchild;
}
if(HuffmanT[c].lchild==-1)
{
output.put(HuffmanT[c].name);
c=2*L.n-2;
}
}
if(ch=='1')
{
if(HuffmanT[c].rchild>=0)
{
c=HuffmanT[c].rchild;
}
if(HuffmanT[c].rchild==-1){
output.put(HuffmanT[c].name);
c=2*L.n-2;
}
}
ch=input.get();
}
input.close();
output.close();
cout<<"保存完?
!
"<}
};
intmain()
{
Function*a=newFunction;
while
(1)//主界面?
示
{
cout<<"************************************"<cout<<"*******?
迎?
入?
/?
?
系?
**********"<cout<<"************************************"<cout<cout<<"*******功能如下:
*******************"<cout<<"*******1.?
取文章并?
字符?
?
*******"<cout<<"*******2.哈夫曼?
?
信息*************"<cout<<"*******3.文章?
?
*******************"<cout<<"*******4.文章?
?
*******************"<cout<<"*******5.退出程序*******************"<cout<charch;
cout<<"====>>?
?
?
功能:
";
cin>>ch;
switch(ch)
{
case'1':
//?
取文章并?
字符?
?
{
deletea;
a=newFunction;
system("cls");
a->CreatHT();
a->CharHuffmanTCoding();
cout<<"操作完?
!
"<system("pause");
system("cls");