信息论与编码课程设计报告设计题目:判断唯一可译码、香农编码专业班级电信12-03学号7学生琳指导教师成凌飞教师评分2015年3月21日目录一、设计任务与要求 (2)二、设计思路 (2)三、设计流程图 (3)四、程序运行及结果 (4)五、心得体会 (6)参考文献 (7)附录:源程序 (8)一、设计任务与要求通过本次课程设计的练习,使学生进一步巩固信源熵、信源编码的基本原理,掌握具体的编码方法,熟悉编程软件的使用,培养学生自主设计、编程调试的开发能力,同时提高学生的实践创新能力。
1、判断唯一可译码利用尾随后缀法判断任意输入的码是否为唯一可译码,即设计一个程序实现判断输入码组是否为唯一可译码这一功能。
2、香农编码熟悉运用香农编码,并能通过C语言进行编程,对任意输入消息概率,利用香农编码方法进行编码,并计算信源熵和编码效率。
二、设计思路1、判断唯一可译码在我们学习使用了克劳夫特不等式之后,知道唯一可译码必须满足克劳夫特不等式。
但是克劳夫特不等式仅仅是存在性的判定定理,即该定理不能作为判断一种码是否为唯一可译码的依据。
也就是说当码字长度和码符号数满足克劳夫特不等式时,则必可以构造出唯一可译码,否则不能构造出唯一可译码。
因此我们必须找到一种能够判断一种码是否为唯一可译码的方法,尾随后缀法。
尾随后缀法算法描述:设C为码字集合,按以下步骤构造此码的尾随后缀集合F:(1) 考查C中所有的码字,若Wi是Wj的前缀,则将相应的后缀作为一个尾随后缀放入集合F0中;(2) 考查C和Fi两个集合,若Wj∈C是Wi∈Fi的前缀或Wi∈Fi 是Wj∈C的前缀,则将相应的后缀作为尾随后缀码放入集合Fi+1中;(3)F包含于Fi即为码C的尾随后缀集合;(4) 若F中出现了C中的元素,则算法终止,返回假(C不是唯一可译码);否则若F中没有出现新的元素,则返回真。
在我们设计的算法中,需要注意的是我们需要的是先输出所有尾随后缀的集合,然后再判断该码是否是唯一可译码,即如F中出现了C中的元素,则C不是唯一可译码,否则若F中没有出现新的元素,则C为唯一可译码。
而不是F 中出现C中的元素就终止,这也是在本题的要求中需要注意的问题。
2、香农编码香农第一定理指出了平均码长与信源之间的关系,同时也指出了可以通过编码使平均码长达到极限值,这是一个很重要的极限定理。
香农第一定理指出,选择每个码字的长度Ki满足下式:I(xi)≤K﹤I(xi)+1,就可以得到这种码。
这种编码方法就是香农编码。
香农编码法有重要的理论意义。
编码步骤如下:(1)将信源消息符号按其出现的概率大小依次排列:p(x1)≥p(x2)≥···≥p(xn)(2)确定满足下列不等式整数码长Ki:-log2p(xi)≤Ki<-log2p(xi)+1(3)为了编成唯一可译码,计算第i个消息的累加概率;(4)将累加概率Pi变成二进制数;(5)取Pi二进制数的小数点后Ki位即为该消息符号的二进制码字。
三、设计流程图1、判断唯一可译码其框图如下:2、香农编码其框图如下:结束四、程序运行及结果1、判断唯一可译码其运行结果如下图所示:2、香农编码其运行结果如下图所示:五、心得体会这次信息论与编码的程序设计,对于我来说是一个挑战。
课程设计是培养学生综合运用所学知识,发现问题、提出问题、分析问题和解决问题的过程,锻炼学生的逻辑思维能力和实践能力,是对学生实际工作能力的具体训练和考察过程。
在整个课程程序中,我们充分应用和调用各个程序模块,从而部分实现了此次程序设计的所应该有的功能。
就是我在课程设计是比较成功的方面,而在这个过程中,让我感觉收获最大的就是我们都能利用这次课程设计学到很多我们在课本上没有的知识,充分的发挥了我们的主动性,使我们学会了自主学习,和独立解决问题的能力。
这次的程序软件基本上运行成功,可以简单的输入进行压缩,并且运用简单的数字告诉程序的操作者下一步该如何进行,使得程序规模相对较小,即功能还不很全面,应用也不很普遍。
总而言之,这次数据结构课程设计让我们感触很深,使我们每个人都了解到学习不应该只局限于课本,因为课本上告诉我们的只是很有限的一部分,只是理论上的死知识,所涉及的围也是狭窄的。
我们若想在有限的围学习到无限的知识,就要我们自己懂得争取,懂得自学,懂得充分利用身边的任何资源。
在我们的程序中有一部分查找许多该方面的资料,我竭力将所获得的信息变成自己的资源。
我动手上机操作的同时,在了解和看懂的基础上对新学的知识进行改进和创新,但是在我们的程序软件中还有很多的不足,需要加以更新。
通过这次课程设计,我们都意识到了自己动手实践的弱势,特别是在编程方面,于是我们知道了计算机的实践操作是很重要的,只有通过上机编程才能充分的了解自己的不足。
通过这次的课程设计,我们深刻意识到自己在学习中的弱点,同时也找到了克服这些弱点的方法,这是在此活动中得到的一笔很大的财富。
同时也感老师给我们这次机会,发现自身存在的缺点与不足,从而在以后的大学生活中更好的提升和完善自我。
参考文献[1]雪虹.信息论与编码[M]. :清华大学,2009.2[2]理工大学概率论与数理统计教研组.概率论与数理统计[M]. :高等教育,2013.4[3]贾宗璞.C语言程序设计[M].:邮电大学,2010附录:源程序1、判断唯一可译码#include <iostream.h>#include <stdlib.h>#include <string.h>struct strings{char *string;struct strings *next;};struct strings Fstr, *Fh, *FP; //输出当前集合void outputstr(strings *str){do{cout<<str->string<<endl;str = str->next;}while(str);cout<<endl;}inline int MIN(int a, int b){ return a>b?b:a; } inline int MAX(int a, int b){ return a>b?a:b; }#define length_a (strlen(CP))#define length_b (strlen(tempPtr))//判断一个码是否在一个码集合中,在则返回0,不在返回1 int comparing(strings *st_string,char *code){while(st_string->next){st_string=st_string->next;if(!strcmp(st_string->string,code))return 0;}return 1;}//判断两个码字是否一个是另一个的前缀,如果是则生成后缀码void houzhui(char *CP,char *tempPtr){if (!strcmp(CP,tempPtr)){cout<<"集合C和集合F中有相同码字:"<<endl<<CP<<endl<<"不是唯一可译码码组!"<<endl;exit(1);}if (!strncmp(CP, tempPtr, MIN(length_a,length_b))){struct strings *cp_temp;cp_temp=new (struct strings);cp_temp->next=NULL;cp_temp->string=new char[abs(length_a-length_b)+1];char *longstr;longstr=(length_a>length_b ? CP : tempPtr);//将长度长的码赋给longstr//取出后缀for (int k=MIN(length_a,length_b); k<MAX(length_a,length_b); k++)cp_temp->string[k - MIN(length_a,length_b)]=longstr[k];cp_temp->string[abs(length_a-length_b)]=NULL;//判断新生成的后缀码是否已在集合F里,不在则加入F集合if(comparing(Fh,cp_temp->string)){FP->next=cp_temp;FP=FP->next;}}}void main(){//功能提示和程序初始化准备cout<<"\t\t唯一可译码的判断!\n"<<endl;struct strings Cstr,*Ch, *CP,*tempPtr;Ch=&Cstr;CP=Ch;Fh=&Fstr;FP=Fh;char c[]="C :";Ch->string=new char[strlen(c)];strcpy(Ch->string, c);Ch->next=NULL;char f[]="F :";Fh->string=new char[strlen(f)];strcpy(Fh->string, f);Fh->next=NULL;//输入待检测码的个数int Cnum;cout<<"输入待检测码的个数:";cin>>Cnum;cout<<"输入待检测码"<<endl;for(int i=0; i<Cnum; i++){cout<<i+1<<" :";char tempstr[10];cin>>tempstr;CP->next=new (struct strings);CP=CP->next;CP->string=new char[strlen(tempstr)] ;strcpy(CP->string, tempstr);CP->next = NULL;}outputstr(Ch);CP=Ch;while(CP->next->next){CP=CP->next;tempPtr=CP;do{tempPtr=tempPtr->next;houzhui(CP->string,tempPtr->string);}while(tempPtr->next);}outputstr(Fh);struct strings *Fbegin,*Fend;Fend=Fh;while(1){if(Fend == FP){cout<<"是唯一可译码码组!"<<endl;exit(1);}Fbegin=Fend;Fend=FP;CP=Ch;while(CP->next){CP=CP->next;tempPtr=Fbegin;for(;;){tempPtr=tempPtr->next;houzhui(CP->string,tempPtr->string);if(tempPtr == Fend)break;}}outputstr(Fh);//输出F集合中全部元素}}2、香农编码#include<iostream.h>#include<math.h>#include<iomanip.h>#include<stdlib.h>class T{public:T() {}~T();void Create();void Coutpxj();void Coutk();void Coutz();void Print();protected:int n;double *p;double *pxj;int *k;double *mz;};void T::Create(){cout<<"请输入信源符号个数:";cin>>n;p=new double[n];cout<<"请分别输入这"<<n<<"个概率:\n";for(int i=0;i<n;i++)cin>>p[i];pxj=new double[n];k=new int[n];mz=new double[n];double sum=0.0;for(i=0;i<n;i++)if(sum!=1.0)throw 1;else{for(i=0;i<n;i++){int k=i;for(int j=i+1;j<n;j++) if(p[k]<p[j]) k=j;double m=p[i];p[i]=p[k];p[k]=m;}}}T::~T(){delete p;delete pxj;delete k;}void T::Coutpxj(){pxj[0]=0;for(int i=1;i<n;i++){pxj[i]=0;for(int j=0;j<i;j++)pxj[i]+=p[j];}}void T::Coutk(){for(int i=0;i<n;i++){double d=(-1)*(log(p[i])/log(2)); if(d-(int)d>0) k[i]=(int)d+1;else k[i]=(int)d;}}void T::Print(){cout<<"Xi"<<setw(8)<<"P(xi)"<<setw(8)<<"Pa(xj)"<<setw(8)<<"Ki"<<setw(8)<<"码字"<<endl;for(int i=0;i<n;i++){ cout<<"X"<<i+1<<setw(8)<<setprecision(2)<<p[i] <<setw(8)<<setprecision(2)<<pxj[i]<<setw(8)<<k[i]<<" ";mz[i]=pxj[i];for(int j=0;j<k[i];j++){if(2*mz[i]-1>=0){cout<<1;mz[i]=2*mz[i]-1;}else{cout<<0;mz[i]=2*mz[i];}}cout<<endl;}double K=0.0,H=0.0,Y;for(i=0;i<n;i++){K+=(double)p[i]*k[i];H+=(-1)*p[i]*(log10(p[i])/log10(2.0)); }Y=H/K;cout<<"平均码长:"<<K<<endl;cout<<"信源熵:"<<H<<endl;cout<<"编码效率:"<<Y<<endl;}void main(){T t;int e;try{t.Create();t.Coutpxj();t.Coutk();t.Print();}catch(int e){if(e==1) cout<<"输入错误,请重新运行";} }。