哈夫曼编码,水题一道。哈夫曼编码的核心是贪心算法,每次取最小的两个数字,然后相加产生新的数字加入数组中,最后只剩下一个数字时,编码结束,在我的博客有专门的哈夫曼编码的讲解,这里就不再叙述了。
另外就是注意当个数为1时,要另外特别处理,否则会出错!!!
下面是代码:180K+0MS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <queue>
#include <vector>
#define Max 1010
#define Inf 1000010
using namespace std;
char record[Max];
int num[30];
int result[60];
int parent[60];
int Sum;
int dfs(int index,int Count){
if(parent[index]==index)
return Count;
else
return dfs(parent[index],Count+1);
}
void cal_min(int number,int &min_first,int &min_second){
int min_value1=Inf,min_value2=Inf;
for(int i=1;i<number;i++)
if(parent[i]==i && result[i]<min_value1){
min_first=i;
min_value1=result[i];
}
for(int i=1;i<number;i++)
if(parent[i]==i && result[i]<min_value2 && i!=min_first){
min_second=i;
min_value2=result[i];
}
}
void hafuman(int number){
int first,second;
int pivot=number;
for(int i=1;i<number-1;i++){
cal_min(pivot,first,second);
result[pivot]=result[first]+result[second];
parent[first]=parent[second]=pivot;
parent[pivot]=pivot;
pivot++;
}
Sum=0;
for(int i=1;i<number;i++)
Sum+=(result[i]*dfs(i,0));
}
int main(){
while(scanf("%s",record)){
if(strcmp(record,"END")==0)
break;
int len=strlen(record);
memset(num,0,sizeof(num));
for(int i=0;i<len;i++){
if(record[i]=='_')
num[0]++;
else
num[record[i]-'A'+1]++;
}
int pivot=1;
for(int i=0;i<=26;i++){
if(num[i]){
result[pivot]=num[i];
parent[pivot]=pivot;
pivot++;
}
}
if(pivot==2){
printf("%d %d 8.0\n",8*len,len);
continue;
}
hafuman(pivot);
printf("%d %d %.1lf\n",8*len,Sum,double(8*len)/Sum);
}
return 0;
}