实现香农编码费诺编码杨兴勃0808060121文档格式.docx
- 文档编号:18046730
- 上传时间:2022-12-13
- 格式:DOCX
- 页数:11
- 大小:43.35KB
实现香农编码费诺编码杨兴勃0808060121文档格式.docx
《实现香农编码费诺编码杨兴勃0808060121文档格式.docx》由会员分享,可在线阅读,更多相关《实现香农编码费诺编码杨兴勃0808060121文档格式.docx(11页珍藏版)》请在冰豆网上搜索。
2.2、算法基本原理
给定某个信源符号的概率分布,通过以下的步骤进行香农编码:
1)信源符号按概率从大到小排列;
2)对信源符号求累加和,表达式:
Pi=Pi-1+p(xi);
3)求自信息量,确定码字长度。
自信息量I(xi)=-log(p(xi));
码字长度取大于等于自信息量的最小整数;
4)将累加和用二进制表示,并取小数点后码字的长度的码。
五、香农编码流程图:
开始
输入符号个数N和相应概率X[i]
按概率由大到小排序
按公式求码长
求出对应位的概率累加和
按乘2取余法则,将累加概率转换为二进制
结合求得的对应码长,将二进制的累加概率取对应长度的作为相应码字
输出信源、概率、累加概率、码长和码字
结束
六、程序设计代码:
#include<
iostream>
math.h>
string>
iomanip>
usingnamespacestd;
voidbubble(double*p,intn)//排序
{
for(inti=0;
i<
n-1;
i++)
{
for(intj=i+1;
j<
n;
j++)
{
if(p[i]<
p[j])
{
doubletemp=p[i];
p[i]=p[j];
p[j]=temp;
}
}
}
}
voidleijia(double*p,double*pa,intn)//累加概率
doublesum=0.0;
pa[i]=sum;
sum+=p[i];
voidlength(double*p,int*k,intn)//码字的长度
for(intj=0;
20;
if(j<
1-log(p[i])/log
(2)&
&
j>
=-log(p[i])/log
(2))
k[i]=j;
doubleI=-log(p[i])/log
(2);
inttemp=int(I);
if(I-temp==0)k[i]=temp;
elsek[i]=temp+1;
voidcode(int*k,double*pa,string*str,intn)//求编码
doubles=pa[i];
k[i];
s=2*s;
if(s>
=1)
str[i]+="
1"
;
s=s-1;
elsestr[i]+="
0"
voidmain()
intn;
cout<
<
"
信源符号个数n="
cin>
>
double*p=newdouble[n];
信源符号的概率依次为:
cin>
p[i];
bubble(p,n);
double*pa=newdouble[n];
leijia(p,pa,n);
int*k=newint[n];
length(p,k,n);
string*str=newstring[n];
code(k,pa,str,n);
setw(10)<
p(ai)"
Pa(aj)"
Ki"
setw(10)
<
码字"
endl;
for(i=0;
{
cout<
p[i]<
pa[i]<
k[i]<
str[i]<
七、实验结果:
八、总结:
通过本次上机,我对香农编码有了进一步的了解,掌握了其具体过程的实现方法,也对新源编码这一概念有了更加深刻的理解,在编码的过程中,是我对C以及C++语言的基础知识掌握更加牢固,特别是巩固了对输出流格式控制的相关知识,总而言之,这次课程设计实践让我受益匪浅。
九、参考文献:
1.《信息论与编码》(第二版)曹雪虹张宗橙编著,清华大学出版社
2.《C/C++语言程序设计》龚尚福主编,中国矿业大学出版社
费诺编码
一、问题描述:
对于给定的信源的概率分布,按照费诺编码的方法进行计算机实现。
二、实习目的:
掌握通过计算机实现费诺编码。
三、算法分析:
3.1、数据结构
本程序采用一个结构体的数据类型来存储费诺编码的相关信息,具体的数据结构如下:
typedefstruct
{
chardata;
floatP;
}Fano[MAX+1];
//需要编码的结构体
3.2、算法基本原理
1)将概率按从大到小的顺序排列;
2)按编码进制数将概率分组,使每组概率和尽可能接近或相等;
3)给每组分配一位码元;
4)将每一分组再按同样原则划分,重复2)和3),直到概率不再可分为止。
四、费诺编码流程图:
输入信源符号个数n、信源符号sign及对应的概率p
按概率从大到小排列,对应的符号也重新排列
信源个数大于2?
通过求累加和确定分组后每组概率累加和尽可能相近或相等。
第一组的信源码字加0,第二组的码字加1
分组点即第一个编号?
分组点为新分组的第一个编号,其他依次……
T
分组点为该组倒数第二个?
F
分组点为新分组的最后一个编号,其他编号不变
以分组点为断点,重新编号分为两组
输出信源符号、概率、码字、码长
五、费诺编码源程序代码:
//全局变量定义
intn;
string*sign;
double*p;
string*code;
voidfano(inta,intb)//费诺编码函数
if((b-a)>
=1)//判断该组中符号个数是否大于2
doublesum=0;
for(inti=a;
=b;
sum+=p[i];
//计算该组概率累加和
doubles1=0,*s=newdouble[10];
for(i=a;
s1+=p[i];
s[i]=fabs(2*s1-sum)/sum;
doublemin=s[a];
intc;
if(s[i]<
=min)
min=s[i];
c=i;
//定位使两组概率和尽可能相近或相等的位置c
if(i<
=c)code[i]+="
//码字加"
elsecode[i]+="
//码字加"
//判断分组点位置,进而分情况自身调用
if(c==a)
fano(c+1,b);
elseif(c==b-1)
fano(a,c);
else
{fano(a,c);
fano(c+1,b);
请输入信源符号个数n:
p=newdouble[n];
sign=newstring[n];
code=newstring[n];
请依次输入信源符号:
i++)cin>
sign[i];
请依次输入信源符号的概率:
p[i]=p[j];
p[j]=temp;
stringm=sign[i];
sign[i]=sign[j];
sign[j]=m;
fano(0,n-1);
//费诺编码
endl<
setw(8)<
信源符号"
概率"
码长"
sign[i]<
code[i]<
code[i].length()<
delete[]p;
delete[]sign;
delete[]code;
六、费诺编码测试结果截图:
七、总结:
费诺编码方法不是唯一。
费诺码比较适合于对分组概率相等或相近的新源编码。
费诺码也可以编。
m进制码,但m越大,信源的符号数越多,可能的编码方式就越多,编码过程就越复杂,有时短吗未必能得到充分利用。
一般情况下,当信源符号个数越多,编码效率就越多低,信源符号相等或越接近,编码效率越高。
八、参考文献:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实现 香农 编码 杨兴勃 0808060121