题很长,仔细看完是哈弗曼编码,原先想着能不能不建树直接求,实在想不出就只能建树了(其中本弱参考了一下课本)。
第一次提交wa了,仔细检查发现只有一个不重复字符时出现了bug
不多说,上本弱的代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct _node{
int ccount,length;
char dta;
int parent;
}arr[64];
int ng1,ng2;
int mycmp(const void *a,const void *b)
{
return ((struct _node*)b)->ccount-((struct _node*)a)->ccount;
}
void select(int num)
{
int i,temp;
for(i=0,temp=-1;i<num;i++)
{
if(!arr[i].parent&&(temp>=arr[i].ccount||temp==-1))
{
ng1=i;
temp=arr[i].ccount;
}
}
for(i=0,temp=-1;i<num;i++)
{
if(!arr[i].parent&&(temp>=arr[i].ccount||temp==-1)&&i!=ng1)
{
ng2=i;
temp=arr[i].ccount;}
}
}
int main(int argc, char const *argv[])
{
char str[10001];
int n,hsz,i,j,siz,f;//n表示共有多少非重复字符
while(gets(str)&&strcmp(str,"END"))
{
hsz=0;
siz=strlen(str);
memset(arr,0,sizeof(arr));
arr[0].dta=str[0];
arr[0].ccount++;
n=1;
for(i=1;i<siz;i++)
{ j=0;
while(str[i]!=arr[j].dta&&j<n)
j++;
arr[j].dta=str[i];
arr[j].ccount++;
if(j>=n) n++;
}
if(n==1) {
printf("%d %d %.1lf\n",8*siz,siz,8.0/1.0 );
continue;
}//因为只有1个不重复字符时,直接处理即可
for(i=n;i<2*n-1;i++)
{
select(i);//获取最小两个没双亲的
arr[i].ccount=arr[ng1].ccount+arr[ng2].ccount;
arr[ng1].parent=arr[ng2].parent=i;
}
for(i=0;i<n;i++)
{
if(!arr[i].dta) continue;
for(f=arr[i].parent;f;f=arr[f].parent)
arr[i].length++;
hsz+=arr[i].length*arr[i].ccount;
}
printf("%d %d %.1lf\n",8*siz,hsz,8*siz/((double)hsz) );
}
return 0;
}