简单题意:给出一组字符串,求出普通编码将占用的位数和哈夫曼编码所用的位数,以及普通编码与哈夫曼编码比率(普通编码长度除以哈夫曼编码长度)。
解题思路形成过程:哈夫曼编码所占用的位数正好等于哈夫曼树各个非根节点的权值之和。因此,将字符储存好后按每个字母的数量将其进行排序,从小到大进行遍历相加进行哈夫曼树的组建,与此同时对哈夫曼树各个非根节点的权值进行累加即可得结果。
#include <iostream>
#include <cstring>#include <stdio.h>
using namespace std;
struct{
int w;
int p;
int l;
int r;
}ASC[60];
int main()
{
char ch[100000];
int hash[35];
int i,j,k;
int lenght;
while(cin>>ch,strcmp(ch,"END")!=0)
{
memset(hash,0,sizeof(hash));
lenght=strlen(ch);
for(i=0;i<lenght;i++)
{
hash[ch[i]-64]++;
}
for(i=1,j=1;i<35;i++)
{
if(hash[i]!=0)
{
ASC[j].w=hash[i];
ASC[j].p=ASC[j].l=ASC[j].r=0;
j++;
}
}
j--;
for(i=j+1;i<j*2;i++)
ASC[i].p=ASC[i].l=ASC[i].r=0;
for(i=j+1;i<j*2;i++)
{
int m1,m2;
m1=m2=999999;
int x1,x2;
for(k=1;k<i;k++)
{
if(ASC[k].w<m1&&ASC[k].p==0)
{
m2=m1;
x2=x1;
m1=ASC[k].w;
x1=k;
}
else if(ASC[k].w<m2&&ASC[k].p==0)
{
m2=ASC[k].w;
x2=k;
}
}
ASC[i].w=m1+m2;
ASC[i].r=x1;
ASC[i].l=x2;
ASC[x1].p=i;
ASC[x2].p=i;
}
int sum=0;
int cnt;
for(i=1;i<j+1;i++)
{
k=i;
cnt=0;
while(ASC[k].p!=0)
{
k=ASC[k].p;
cnt++;
}
sum+=cnt*ASC[i].w;
}
if(j==1)
sum=lenght;
float ratio;
ratio=float(lenght*8)/sum;
printf("%d %d %.1f\n",lenght*8,sum,ratio);
}
return 0;
}