1. 程式人生 > >費諾編碼C程式及演示結果

費諾編碼C程式及演示結果

費諾編碼

功能簡介:首先輸入信源符號的個數,然後輸入各個信源符號的概率。(概率之和等於1)

主程式:  李松林

#include<stdio.h>     湖北師範學院

#include<math.h>

#define G 20

int function1(int c,int M);

void function2(int c,int num1,int M,int cs);

void function3(int c,int M);

float a[G]={0},tmp=0,m[G]={0},k=0,H=0,num[G]={0},sum1=0,sum2=0;

int K[G]={0},i,j,N,s[G][G],c,cs=0,num1=0,ks[G],zj[G],zh[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=0;i<N;i++)

{

m[i]=-log10(a[i])/log10(2.0);//求出-log p(ai)並儲存在陣列m

}

/////////////////////////////////////////////////////////////////////////////

   function3(0,N);

    for(i=0;i<N;i++)

{

 H+=a[i]*m[i];//求信源熵

 k+=a[i]*K[i];//平均碼長

}

printf("信源訊息符號ai  符號概率p(ai)    碼長Ki      二元碼字\n");

for(i=0;i<N;i++)

{

      printf("     a%d           %-4.2f              %d           ",i+1,a[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));

 }

}

int function1(int c,int M)//求出分界點

{

int d=c;

    for(i=c;i<M-1;i++)

{

  for(j=c;j<i+1;j++)

sum1+=a[j];

  for(j=i+1;j<M;j++)

sum2+=a[j];

      num[i]=fabs(sum1-sum2);//取絕對值

  sum1=0;

  sum2=0;

}

for(i=c;i<M-1;i++)

{

  if(num[d]>num[i])

  d=i;

}

   d+=1;

   return d;

}

void function2(int c,int num1,int M,int cs)//進行分組並計算碼長、碼字

{

   for(i=c;i<num1;i++)

{

  s[i][cs]=0;

  K[i]+=1;

}

for(j=num1;j<M;j++)

{

  s[j][cs]=1;

  K[j]+=1;

}

}

void function3(int c,int M)

{

 num1=function1(c,M);

 function2(c,num1,M,cs);

 ks[cs]=c;

 zj[cs]=num1;

 zh[cs]=M;

 cs++;

 if((zj[cs-1]-ks[cs-1])>1)

 {

function3(ks[cs-1],zj[cs-1]);

 }

 if((zh[cs-1]-zj[cs-1])>1)

 {

   function3(zj[cs-1],zh[cs-1]);

 }

 cs--;

}

第一次輸入: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

結果: