信息理论及编码实验指导书.docx
- 文档编号:27040383
- 上传时间:2023-06-26
- 格式:DOCX
- 页数:52
- 大小:96.61KB
信息理论及编码实验指导书.docx
《信息理论及编码实验指导书.docx》由会员分享,可在线阅读,更多相关《信息理论及编码实验指导书.docx(52页珍藏版)》请在冰豆网上搜索。
信息理论及编码实验指导书
信息理论与编码实验指导书
解振东编写
信息科学与技术学院
实验一:
香农(Shannon)编码
一、实验目的
掌握通过计算机实现香农编码的方法。
二、实验要求
对于给定的信源的概率分布,按照香农编码的方法进行计算机实现。
三、实验基本原理
给定某个信源符号的概率分布,通过以下的步骤进行香农编码
1.将信源消息符号按其出现的概率大小排列
2.确定满足下列不等式的整数码长Ki;
3.为了编成唯一可译码,计算第i个消息的累加概率
4.将累加概率Pi变换成二进制数。
5.取Pi二进制数的小数点后Ki位即为该消息符号的二进制码。
四实验内容
1.对给定信源
进行二进制香农编码。
2.对给定信源
进行二进制香农编码。
3.自已选择一个例子进行香农编码。
五、实验设备
PC计算机,C++
六、实验报告要求
1、画出程序设计的流程图,
2、写出程序代码,
3、写出在调试过程中出现的问题,
4、对实验的结果进行分析。
七、参考程序(仅供参考)
//香农(Shannon)编码参考程序
intmain()
{
intN;
cout<<”请输入信源符号个数:
”;cin>>N;
cout<<”请输入各符号的概率:
”< double*X=newdouble[N];//离散无记忆信源 inti,j; for(i=0;i { cout<<”X[”<>X[i]; } //由小到大排序 for(i=0;i for(j=i+1;j if(X[i] {doubletemp=X[i];X[i]=X[j];X[j]=temp;} int*K=newint[N];//确定码长 for(i=0;i { K[i]=int(-(log(X[i])/log (2)))+1;//确认码长为1-log2(p(xi)) if(K[i]==(-(log(X[i])/log (2)))+1)//当K[i]=-log2(p(xi))时,K[i]-- K[i]--; } //累加概率 double*Pa=newdouble[N];pa[0]=0.0; for(i=1;i pa[i]=pa[i-1]+X[i-1]; //将累加概率转换为二进制 string*code=newstring[N]; for(i=0;i for(j=0;j { doubletemp=Pa[i]*2; if(temp>=1)//累加概率乘2大于1,对应码字加1,累加概率自身取余 { code[i]+=”1”; Pa[i]=Pa[i]*2-1; } else//累加概率乘2小于1时,对应码字加0,累加概率自身取余 { code[i]+=”0”; Pa[i]*=2; } } for(i=0;i code[i]=code[i].substr(0,K[i]);//求码字 //输出码字 cout< for(i=0;i cout< delete[]X; delete[]Pa; delete[]K; delete[]code; getch(); retuen0; } 实验二费诺编码 一、实验目的 掌握通过计算机实现费诺编码。 二、实验要求 对于给定的信源的概率分布,按照费诺编码的方法进行计算机实现。 三、实验基本原理 费诺编码的步骤: 1.将概率按从大到小的顺序排列; 2.按编码进制数将概率分组,使每组概率和尽可能接近或相等; 3.给每组分配一位码元; 4.将每一分组再按同样原则划分,重复2和3,直到概率不再可分为止。 四实验内容 1.对给定信源 进行二进制费诺编码。 2.对给定信源 进行二进制费诺编码。 3.自已选择一个例子进行费诺编码。 五、实验设备 PC计算机,C++ 六、实验报告要求 1、画出程序设计的流程图, 2、写出程序代码, 3、写出在调试过程中出现的问题, 4、对实验的结果进行分析。 七、参考程序(仅供参考) //********费诺编码参考程序1**** //全局变量定义 intn; string*sign; double*p; string*code; voidfano(inta,intb)//费诺编码函数 { if((b-a)>=1)//判断该组中符号个数是否大于2 { doublesum=0; for(inti=a;i<=b;i++) sum+=p[i];//计算该组概率累加和 doubles1=0,*s=newdouble[10]; for(inti=a;i<=b;i++) { s1+=p[i];s[i]=fabs(2*s1-sum)/sum; } doublemin=s[a];intc; for(inti=a;i<=b;i++) if(s[i]<=min) { min=s[i];c=i;//定位使两组概率和尽可能相近或相等的位置c } for(inti=a;i<=b;i++) { if(i<=c)code[i]+=”0”;//码字加“0” elsecode[i]+=”1”;//码字加“1” } //判断分组点位置,进而分情况自身调用 if(c==a) fano(c+1,b); elseif(c==b-1) fano(a,c); else {fano(a,c);fano(c+1,b);} } } voidmain() { cout<<””请输入信源符号个数n: ”; cin>>n; p=newdouble[n]; sign=newstring[n]; code=newstring[n]; cout<<”请输入信源符号: ”; for(inti=0;i cout<<”请输入信源符号的概率: ”; for(inti=0;i for(inti=0;i for(intj=i+1;j if(p[i] { doubletemp=p[i];p[i]=p[j];p[j]=temp; stringm=sign[i];sign[i]=sign[j];sign[j]=m; } fano(0,n-1);//费诺编码 cout< for(inti=0;i cout< delete[]p;delete[]sign;delete[]code; } //***********费诺编码参考程序2************* #include #include usingnamespacestd; classDATA//数据类,采用双向表 { public: //初始化PXi=1是为了在排序迭代时方便 DATA(){next=NULL;pre=NULL;r=NULL;PXi=1;key[0]='\0';key[1]='\0';key[2]='\0';key[3]='\0';key[4]='\0';key[5]='\0'; key[6]='\0';key[7]='\0';key[8]='\0';key[9]='\0';key[10]='\0';} charXi;//信源符号 doublePXi;//信源概率 charkey[11];//码字 DATA*next,*pre,*r;//地址 }; DATA*head=newDATA,*p=head; intk=(-1);//编码函数用 voidencoding(DATA*pp);//编码函数声明 DATA*sort(DATA*pp);//排序函数声明 DATA*HEAD=newDATA,*tt=HEAD,*T;//排序函数用 voidinput()//输入数据 { doublel,sum=0; intn,i; charL; cout<<"请输入信源个数: "; cin>>n; for(i=0;i { cout<<"请输入一个字符的信源符号: "< cout<<"请输入概率: "< p->Xi=L; p->PXi=l; sum=sum+p->PXi; p->next=newDATA; p->next->pre=p;//对新创建结点赋值 p->r=p->next; p=p->next; } if(sum! =1) { cout<<"所输入的概率之和是"< input(); } T=sort(head);//因为sort要改变tt,故需要一个中间变量 tt->next=T;//由于迭代产生的链表格式不规范,以下句用来整理sort函数的返回结果 tt->next->pre=tt; tt=tt->next; tt->next=newDATA; tt->next->pre=tt;//对新创建结点赋值 tt=tt->next; HEAD->next->next->pre=NULL; HEAD=HEAD->next->next; cout<<"对输入信源排序结果如下: "< for(p=HEAD;p->next! =NULL;p=p->next)//排序输出 cout< "< cout<<"对输入信源编码结果如下: "< encoding(HEAD); } /***********************编码************************/ voidencoding(DATA*pp)//定义递归函数 { doubley=1;//y定义为1是因为概率最多为1 k++;//递归自增值,用于字符数组定位 DATA*head1=pp,*head2; into=1; while (1)//分01组 { doublel=0,z=0; for(inti=1;i<=o;i++) { if(pp->next==NULL)break; l=l+pp->PXi; pp=pp->next; } head2=pp->pre;//从这里分01段 for(;pp->next! =NULL;pp=pp->next) z=z+pp->PXi; if(y>fabs(l-z))//判断两组值之差是否最小 { y=fabs(l-z); pp=head1; o++; continue; } elseif(z==0&&i<=2)//z=0,i<1表示只有一个概率了 { cout< "< break; } for(DATA*u=head1;u->next! =head2->next;u=u->next) u->key[k]='0';//为字符串赋值 for(DATA*h=head2;h->next! =NULL;h=h->next) h->key[k]='1'; head2->pre->next=newDATA;//分段: 标记head2为上一段结束位置 head2->pre->next->pre=head2->pre; encoding(head1);//递归 encoding(head2); break; } k--;//迭代还原到上一个数组位置 } DATA*sort(DATA*pp) {//函数递归后头变到HEAD->next->next.返回值得到最后个head2没有与tt相连,需另设.得不到结尾为空的(next=MULL)地址 DATA*head1=pp,*head2=pp; if(pp->next==NULL)returnpp;//当pp是最后一个值时 for(;pp->next! =NULL;pp=pp->next) { if(1-pp->PXi>=1-head2->PXi)//两个以上的值时,由于最后一个pxi为1,所以每次都会有个最小值 head2=pp; } if(head2->pre==NULL)//当pp是第一个值时 { head2->next->pre=NULL; head1=head1->next; } else//当pp是最后一个值及中间的值时 { head2->pre->next=head2->next; head2->next->pre=head2->pre; } tt->next=sort(head1);//递归,先得第一个,再得下一个 tt->next->pre=tt; tt=tt->next; returnhead2; } voidmain() { cout<<"************费诺编码************"< input(); cout< } 实验三霍夫曼编码 一、实验目的 掌握通过计算机实现霍夫曼编码 二、实验要求 对于给定的信源的概率分布,按照霍夫曼编码的方法进行计算机实现。 三、实验基本原理 霍夫曼编码的步骤: (1).把信源符号按概率大小顺序排列,并设法按逆次序分配码字的长度。 (2).在分配码字长度时,首先将出现概率最小的两个符号的概率相加合成一个概率 (3).把这个合成概率看成是一个新组合符号地概率,重复上述做法直到最后只剩下两个符号概率为止。 (4).完成以上概率顺序排列后,再反过来逐步向前进行编码,每一次有二个分支各赋予一个二进制码,可以对概率大的赋为0,概率小的赋为1。 四实验内容 1.对给定信源 进行二进制霍夫曼编码。 2.对给定信源 进行二进制霍夫曼编码。 3.自已选择一个例子进行霍夫曼编码。 五、实验设备 PC计算机,C++ 六、实验报告要求 1、画出程序设计的流程图, 2、写出程序代码, 3、写出在调试过程中出现的问题, 4、对实验的结果进行分析。 七、参考程序(仅供参考) //第一段参考代码 #include #include #include usingnamespacestd; //==================== typedefstruct { intweight; intparent; intlchild; intrchild; }hnodetype;//霍夫曼树节点 typedefstruct { intbit[10]; intposition; charsign; }hcodetype;//霍夫曼编码表 //======================= voidHuffman(intm[],intn);//函数声明 intmain() { inti=0,n=8; intm[10]={40,18,10,10,7,6,5,4}; charsign[10]="hufmcode"; cout< "; for(i=0;i cout< cout< "; for(i=0;i { floatf=(float)m[i]/100; cout< } cout< "< Huffman(m,n); getch(); return0; } //==================================== voidHuffman(intm[],intn) { inti,j,m1,m2,x1,x2,c,p; hnodetype*huffnode=newhnodetype[2*n-1];//一共2n-1个节点 hcodetype*huffcode=newhcodetype[n],temp; for(i=0;i<2*n-1;i++) {//初始化霍夫曼树 huffnode[i].weight=0; huffnode[i].parent=0; huffnode[i].lchild=1; huffnode[i].rchild=1; } for(i=0;i {//节点赋初值 huffnode[i].weight=m[i]; huffcode[i].sign=sign[i]; } //对n到2n-1节点编码 for(i=0;i { m1=m2=100; x1=x2=0; for(j=0;j { if(huffnode[j].weight<=m1&&huffnode[j].parent==0) { m2=m1;x2=x1; m1=huffnode[j].weight; x1=j; } elseif(huffnode[j].weight<=m2&&huffnode[j].parent==0) { m2=huffnode[j].weight; x2=j; } } huffnode[x1].parent=n+i;//定义x1和x2的父节点为n+i huffnode[x2].parent=n+i; huffnode[n+i].weight=huffnode[x1].weight+huffnode[x2].weight; huffnode[n+i].lchild=x1;//新节点的左、右孩子分别为x1、x2 huffnode[n+i].rchild=x2; } //从叶子到根逆向求每个字符的霍夫曼编码 for(i=0;i { temp.position=n-1; c=i; p=huffnode[c].parent; while(p! =0)//如果p节点不是根节点则一直向上编码 { if(huffnode[p].lchild==c)//如果p节点的左孩子是c,则码字加1 temp.bit[temp.position]=1; else//否则则码字加0 temp.bit[temp.position]=0; temp.position--;//记录当前码字存储位置 c=p;p=huffnode[c].parent;//从新定义c和p的指向 } cout< "; for(j=temp.position+1;j {//输出码字 huffcode[i].bit[j]=temp.bit[j]; cout< } cout< } delete[]huffcode; delete[]huffnode; } //第二段参考代码 #include #include #include #include #include //------ typedefstruct{ unsignedintweight; unsignedintparent,lchild,rchild; }HTNode,*HuffmanTree; typedefchar**HuffmanCode; typedefstruct{ unsignedints1; unsignedints2; }MinCode; voidError(char*message); HuffmanCodeHuffmanCoding(HuffmanTreeHT,HuffmanCodeHC,unsignedint*w,unsignedintn); MinCodeSelect(HuffmanTreeHT,unsignedintn); voidError(char*message) { clrscr(); fprintf(stderr,"Error: %s",message); exit (1); } HuffmanCodeHuffmanCoding(HuffmanTreeHT,HuffmanCodeHC,unsignedint*w,unsignedintn) { unsignedinti,s1=0,s2=0; HuffmanTreep; char*cd; unsignedintf,c,start,m; MinCodemin; if(n<=1)Error("Codetoosmall! "); m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); for(p=HT,i=0;i<=n;i++,p++,w++) { p->weight=*w; p->parent=0; p->lchild=0; p->r
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 信息 理论 编码 实验 指导书