哈夫曼编码C程序及演示结果
2015-11-16 11:02
344 查看
哈夫曼编码
功能简介:首先输入信源符号的个数,然后输入各个信源符号的概率。(概率之和等于1)
主程序 李松林
#include<stdio.h> 湖北师范学院
#include<math.h>
#define G 20
void qiumazi(int M); //求码字
struct abc
{
int b;
int d[G];
//float c[G];
float num;
}D[G],E;
float a[G]={0},f[G],tmp=0,m[G]={0},k=0,H=0;
int K[G]={0},i,j,N,s[G][G]={0},cs=0;
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++)
{
D[i].b=1;
D[i].d[0]=i;
//D[i].c[0]=a[i];
D[i].num=a[i];
}
for(i=0;i<N;i++)
{
m[i]=-log10(a[i])/log10(2.0); //求出-log p(ai)并保存在数组m里
}
qiumazi(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=K[i];j>0;j--)
printf("%d",s[i][j-1]);
printf("\n");
}
printf("信源熵H=%5.3f bit/符号 费诺码的平均码长k=%5.3f 码元/符号 编码效率n=%4.1f%% \n",H,k,100*(H/k));
}
}
void qiumazi(int M) //求码字
{
for(i=0;i<M-1;i++)
for(j=i+1;j<M;j++)
if(D[i].num<D[j].num)
{
E=D[i];
D[i]=D[j];
D[j]=E;
}
for(i=0;i<D[M-2].b;i++)
{
j=D[M-2].d[i];
s[j][K[j]]=0;
K[j]+=1;
}
for(i=0;i<D[M-1].b;i++)
{
j=D[M-1].d[i];
s[j][K[j]]=1;
K[j]+=1;
}
D[M-2].num+=D[M-1].num;
for(i=0;i<D[M-1].b;i++)
{
D[M-2].d[i+D[M-2].b]=D[M-1].d[i];
// D[M-2].c[i+D[M-2].b]=D[M-1].c[i];
}
D[M-2].b+=D[M-1].b;
/**********这样可以获得较小的码方差************/
/* E=D[0];
D[0]=D[M-2];
D[M-2]=E;*/
/**********码方差越小编码的质量越好***********/
M--;
if(M>1)
{
cs++;
qiumazi(M);
}
}
第一次输入:5 0.4 0.2 0.2 0.1 0.1
结果是:
第二次输入: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
结果是:
功能简介:首先输入信源符号的个数,然后输入各个信源符号的概率。(概率之和等于1)
主程序 李松林
#include<stdio.h> 湖北师范学院
#include<math.h>
#define G 20
void qiumazi(int M); //求码字
struct abc
{
int b;
int d[G];
//float c[G];
float num;
}D[G],E;
float a[G]={0},f[G],tmp=0,m[G]={0},k=0,H=0;
int K[G]={0},i,j,N,s[G][G]={0},cs=0;
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++)
{
D[i].b=1;
D[i].d[0]=i;
//D[i].c[0]=a[i];
D[i].num=a[i];
}
for(i=0;i<N;i++)
{
m[i]=-log10(a[i])/log10(2.0); //求出-log p(ai)并保存在数组m里
}
qiumazi(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=K[i];j>0;j--)
printf("%d",s[i][j-1]);
printf("\n");
}
printf("信源熵H=%5.3f bit/符号 费诺码的平均码长k=%5.3f 码元/符号 编码效率n=%4.1f%% \n",H,k,100*(H/k));
}
}
void qiumazi(int M) //求码字
{
for(i=0;i<M-1;i++)
for(j=i+1;j<M;j++)
if(D[i].num<D[j].num)
{
E=D[i];
D[i]=D[j];
D[j]=E;
}
for(i=0;i<D[M-2].b;i++)
{
j=D[M-2].d[i];
s[j][K[j]]=0;
K[j]+=1;
}
for(i=0;i<D[M-1].b;i++)
{
j=D[M-1].d[i];
s[j][K[j]]=1;
K[j]+=1;
}
D[M-2].num+=D[M-1].num;
for(i=0;i<D[M-1].b;i++)
{
D[M-2].d[i+D[M-2].b]=D[M-1].d[i];
// D[M-2].c[i+D[M-2].b]=D[M-1].c[i];
}
D[M-2].b+=D[M-1].b;
/**********这样可以获得较小的码方差************/
/* E=D[0];
D[0]=D[M-2];
D[M-2]=E;*/
/**********码方差越小编码的质量越好***********/
M--;
if(M>1)
{
cs++;
qiumazi(M);
}
}
第一次输入:5 0.4 0.2 0.2 0.1 0.1
结果是:
第二次输入: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
结果是:
相关文章推荐
- 改善Java程序的151个建议--记录(持续更新)
- 在eclipseAndroid之打包生成apk
- 25个让Java程序员更高效的Eclipse插件
- Field "state" doesn't have a default value
- 获得字符串的宽度
- 状态栏白色调节
- Spring获取资源文件
- PHP扩展代码结构详解
- H5页面调用android上传,支持input-file
- xshell经典配色方案
- 解决手机浏览器和微信中select中border:none;无用和去掉小三角
- CS0016: 未能写入输出文件“c:\WINDOWS\Microsoft.NET\Framework\.。。”--“拒绝访问(已解决)
- PHP 7 的几个新特性
- glusterfs rebalance
- Java多线程基础
- Apache开启Gzip
- java架构师之路:JAVA程序员必看的15本书的电子版下载地址
- 跟我学习javascript的函数和函数表达式
- android编程实现添加文本内容到sqlite表中的方法
- (8)分布式下的爬虫Scrapy应该如何做-图片下载(源码放送)