#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define H 6666666
struct ff
{
int w; //权值
int p; //父节点
int l; //左孩子
int r; //右孩子
}ff[100];
char str[50000];
int dit[28],min1,min2,g1,g2,sum1,v,sum2;
int main()
{
int i,j,k;
while(scanf("%s",str)!=EOF)
{
if(strcmp(str,"END")==0)break;
memset(dit,0,sizeof(dit));
for(i=0;i<100;i++)
ff[i].w=ff[i].p=ff[i].l=ff[i].r=0;//初始化
for(i=0;i<strlen(str);i++)
if(str[i]>='A'&&str[i]<='Z')dit[str[i]-'A']++;//统计大写字母出现的次数
else dit[26]++; //统计下划线出现的次数
//for(i=0;i<27;i++)
//if(dit[i])printf("%d ",dit[i]);
//printf("------\n");
// 在此犯了一个错:忘记了只有一个字符时的编码情况
//看到别人的代码对于出现其他字符的情况也做了处理,我的仅仅是对
//所要求的字符进行了处理
k=1;
for(i=0;i<27;i++)
if(dit[i]) ff[k++].w=dit[i];
if(k==2)printf("%d %d %.1lf\n",ff[k-1].w*8,ff[k-1].w,ff[k-1].w*8.0/ff[k-1].w);
else
//printf("%d\n",k);
{ //建立哈夫曼树
for(i=k;i<(k-1)*2;i++)
{
min1=min2=H;
for(j=1;j<i;j++)
if(!ff[j].p&&ff[j].w<min1)
{
min1=ff[j].w;
g1=j;
}
ff[g1].p=i;
for(j=1;j<i;j++)
if(!ff[j].p&&ff[j].w<min2)
{
min2=ff[j].w;
g2=j;
}
ff[g2].p=i;
ff[i].l=g1;
ff[i].r=g2;
ff[i].w=min1+min2;
}
//for(i=1;i<2*(k-1);i++)
//printf("%d %d %d %d\n",ff[i].w,ff[i].p,ff[i].l,ff[i].r);
//计算哈夫曼编码的长度
sum1=sum2=0;
for(i=1;i<k;i++)
{
j=ff[i].p;
v=0;
for(;j!=0;j=ff[j].p)
v++;
sum1=sum1+ff[i].w*v;
sum2=sum2+ff[i].w;
}
sum2=sum2*8;
printf("%d %d %.1lf\n",sum2,sum1,sum2*1.0/sum1);
}
}
system("pause");
return 0;
}
poj 1521(哈夫曼编码)
最新推荐文章于 2020-04-28 16:12:04 发布