poj 1521(哈夫曼编码)

#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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值