实验一:Huffman编码软件实现(三学时)
1、实验目的
(1)加深理解Huffman编码原理;
(2)掌握C或C++语言程序设计和调试技术
2、实验要求
(1)输入:信源符号个数r、信源的概率分布P;
(2)输出:每个信源符号对应的Huffman编码的码字。
3、实验内容
1、从键盘输入组成信源C的字符个数N;
2、从键盘输入信源C和组成信源的字符所对应的概率数组P;
3、给出每个信源符号的Huffman编码输出
4、实验报告
(1)总结Huffman编码的原理与特点
(2)写出Huffman编码的基本步骤,画出实现Huffman编码的程序流程图
(3)给出Huffman编码的源程序,并给出编码结果
(4)总结实验过程遇到的问题及解决方法
实验二 循环码的编码和译码程序设计(三学时)
一、实验目的:
1、加深理解循环码的编码原理。
2、加深理解循环码的译码方法。
3.分析循环码的纠错能力。
二、实验要求:
1、给出编、译码流程图。使用生成多项式g(x)进行编码。如(7.3)码,生成多项式取g(x)=x^4+x^2+ x +1
2、使用C语言进行编程。
3、给出程序清单。
4、出示编码和译码结果.
三、实验设计原理
1、循环码编码原理
设有一(n,k)循环码,码字C=[Cn-1…CrCr-1…C0],其中r=n-k。码字多项式为:
C(x)= Cn-1xn-1+Cn-2xn-2+…C1x+C0。
码字的生成多项式为: g(x)=gr-1xr-1gr-2xr-2+…+g1x+g0
待编码的信息多项式为: m(x)=mK-1xK-1+…+m0
xn-k.m(x)=Cn-1xn-1+…+Cn-Kxn-K
对于系统码有: Cn-1=mK-1,Cn-2=mK-2,…Cn-K=Cr=m0
设监督多项式为: r(x)=Cr-1Xr-1+…+C1x+C0
根据循环码的定义,则有:
C(x)=xn-Km(x)+r(x)=q(x).g(x)
Xn-Km(x)=q(x).g(x)+r(x)
r(x)=Rg(x)[xn-Km(x)]
即监督多项式是将多项式xn-Km(x)除以g(x)所得的余式。
编码过程就是如何根据生成多项式完成除法运算求取监督多项式的过程。
设循环码(7.3)码的字多项式为:
C(x)=C6x6+C5x5+C4x4+C3x3+C2x2C1x+C0 (n=7)
生成多项式为: g(x)=x4+x2+x+1
信息多项式为: m(x)=m2x2+m1x+m0 (k=3), 设m(x)=x2+x
监督多项式为: r(x)= Cr-1Xr-1+…+C1x+C0
根据循环码的定义:生成多项式的倍式均是码字,编码实际上是做xn-km(x)除以g(x)的
运算求得r(x)。
编码程序框图见图1(a)左,二进制多项式除法示意图见图1(b)。
2、译码原理
设R(x)为接收码字多项式,E(x)为错误图样多项式,S(x)为伴随式,则根据循环码的性质有:
S(x)=Rg(x)[R(x)]=Rg(x)[E(x)]
当R(x)=C(x)时,有E(x)=0,S(x)=0
当R(x)不等于C(x)时,有E(x)为非0,S(x)为非0
(a)编码计算程序框图 (b)二进制多项式除法示意图
图1编码计算程序框图及多项式除法示意图
译码过程如下:
计算每一种可能被纠的错误图样E(x)的伴随式,
Si(x)=Rg(x)[E(x)]
本地作数据表存储好。
根据已接收码字多项式R(x),计算相应的伴随式:
S(x)=Rg(x)[R(x)]
将实际接收码字求出的S(x)与本地存储的各Si(x)相比较,查出两者相等的那个唯一匹配的Si(x),找出并得到相应的错误图样E(x)。
(4) 纠错: C(x)=R(x)+E(x)
否则由S(x)找不出唯一匹配的Si(x),则报出错信息,表示出现不可纠错的错误图样,即码元出错的个数超出该循环码的纠错能力。
译码流程图2所示:
六、完成实验报告
(1)简要总结循环码编译码原理与特点
(2)写出循环码的基本步骤,画出实现循环码的程序流程图
(3)给出循环码的源程序,并给出实验过程中的测试结果
(4)总结实验过程遇到的问题及解决方法
实验代码及结果:
include<iostream>
include<vector>
include<algorithm>
usingnamespacestd;
structnnode{
floatp;
nnodeparent=NULL;
nnoderchild=NULL;
nnodelchild=NULL;
};
boolGSort(nnodea,nnodeb){return(a.p>b.p);}
voidbianli(nnode&head,stringstr){
if(head->lchild!=NULL){
bianli(head->lchild,str+"1");
}
if(head->rchild!=NULL){
bianli(head->rchild,str+"0");
}
if(head->rchild==NULL&&head->lchild==NULL){
cout<<"概率"<<head->p<<"的霍夫曼编码是:"<<str<<endl;
}
}
intmain(intargc,charargv){
cout<<"请输入信源符号个数"<<endl;
intn;
cin>>n;
cout<<"请输入分布概率"<<endl;
vector<nnode>v;
floata=0;
for(inti=0;i<n;i++){
nnodep1;
p1.lchild=NULL;
p1.parent=NULL;
p1.rchild=NULL;
cin>>p1.p;
v.push_back(p1);
a+=p1.p;
}
if(a!=1){
cout<<"错误!分布概率之和不为0"<<endl;
return0;
}
sort(v.begin(),v.end(),GSort);
nnoderoot=newnnode;
for(intj=0;j<n-1;j++){
nnodepnode=newnnode;
nnodeleft=newnnode;
left=v.back();
v.pop_back();
nnoderight=newnnode;
right=v.back();
v.pop_back();
pnode->p=right->p+left->p;
pnode->rchild=right;
pnode->lchild=left;
right->parent=left->parent=pnode;
for(vector<nnode>::iteratork=v.begin();k<=v.end();k++){
nnodep2=k;
if(pnode->p>=p2.p){
v.insert(k,pnode);
break;
}else{
if(k==v.end()){
v.push_back(pnode);
}
}
}
root=pnode;
}
cout<<"霍夫曼编码如下(概率大的用短码,概率小的用长码):"<<endl;
bianli(root,"");
return0;
}