香农编码
功能简介:首先输入信源符号的个数,然后输入各个信源符号的概率。(概率之和等于1)
主程序 : 李松林
#include<stdio.h> 湖北师范学院
#include<math.h>
#define G 20
float a[G]={0},P[G]={0},tmp=0,m[G]={0},k=0,H=0;
int K[G]={0},i,j,N,s[G][G];
void main()
{
loop:printf("请输入信源符号个数N:");
scanf("%d",&N);
for(i=0;i<N;i++)
{
scanf("%f",&a[i]);
tmp+=a[i];
}
if(tmp<0.9999||tmp>1.0001)
{
printf("输入的数据不符合要求,请重新输入\n");
tmp=0;
goto loop;
}
else
{
for(i=0;i<N-1;i++) //从大到小进行排序
for(j=i+1;j<N;j++)
{
if(a[i]<a[j])
{
tmp=a[i];
a[i]=a[j];
a[j]=tmp;
}
}
for(i=1;i<N;i++) //求累加概率
for(j=0;j<i;j++)
P[i]+=a[j];
for(i=0;i<N;i++)
{
m[i]=-log10(a[i])/log10(2.0); //求出-log p(ai)并保存在数组m里
for(j=0;j<10;j++) //对存在数组m里的数进行取整(取不小于这个数的最小整数)
{
if(m[i]==j)
{
K[i]=j;
break;
}
if(m[i]>j&&m[i]<j+1)
{
K[i]=j+1;
break;
}
}
}
for(i=0;i<N;i++) //求码字
{
tmp=P[i];
for(j=0;j<K[i];j++)
{
tmp=tmp*2;
if(tmp<1)
s[i][j]=0;
else
{
s[i][j]=1;
tmp=tmp-1;
}
}
}
for(i=0;i<N;i++)
{
H+=a[i]*m[i]; //求信源熵
k+=a[i]*K[i]; //求平均码长
}
printf("信源消息符号ai 符号概率p(ai) 累加概率Pi -log p(ai) 码字长度Ki 码字\n");
for(i=0;i<N;i++)
{
printf(" a%d %-4.2f %-4.2f %-4.2f %d ",i+1,a[i],P[i],m[i],K[i]);
for(j=0;j<K[i];j++)
printf("%d",s[i][j]);
printf("\n");
}
printf("信源熵H=%5.3f bit/符号 香农码的平均码长k=%5.3f 码元/符号 编码效率n=%4.1f%% \n",H,k,100*(H/k));
}
}
第一次输入:6 0.32 0.22 0.18 0.16 0.08 0.04
结果:
第二次输入:7 0.20 0.19 0.18 0.17 0.15 0.10 0.01
结果:
第三次输入:8 0.1 0.18 0.4 0.05 0.06 0.1 0.07 0.04
结果: