http://acm.hdu.edu.cn/showproblem.php?pid=1053
题目标题:entropy
题目大意:将一串字符串用哈夫曼树的方法压缩,求压缩前与压缩后所占空间与压缩比例
这个题是数据结构中哈夫曼树的应用,把每个字符出现的次数记录下来,每次把最少的两个合成一个结点,并由此得到哈夫曼树,然后对每个节点编码,向左标0,向右标1,得到每个字母的编码后计算空间即可。需要注意只有一个字符的情况。
#include<iostream>
#include<stdio.h>
#include<stdlib.h>
#include<vector>
#include<algorithm>
using namespace std;
int sum1=0,sum2=0;
struct Node{
char value;
int num;
Node* left=NULL;
Node* right=NULL;
};
Node* make(Node *a,Node *b){
Node *p;
p=(Node*)malloc(sizeof(Node));
p->left=a;
p->right=b;
p->value=1;
p->num=a->num+b->num;
return p;
}
bool Judge(Node *a,Node *b){
if(a->num > b->num) return true;
else return false;
}
void DFS(Node *a,int cur){
if(a->left==NULL && a->right==NULL){
sum2+=cur*a->num;
return;
}
else {
if(a->left!=NULL)
DFS(a->left,cur+1);
if(a->right!=NULL)
DFS(a->right,cur+1);
}
free(a);
}
int main()
{
vector <Node*> Vec;
string x;
while(cin>>x){
sum1=0;
sum2=0;
if(x=="END") break;
sum1=x.size()*8;
for(int i=0;i<x.size();i++){
int sign=0;
for(int j=0;j<Vec.size();j++){
if(x[i]==Vec[j]->value){
sign=1;
Vec[j]->num++;
break;
}
}
if(sign==0){
Node* p;
p=(Node*)malloc(sizeof(Node));
p->value=x[i];
p->num=1;
p->left=NULL;
p->right=NULL;
Vec.push_back(p);
}
}
int n=Vec.size()-1;
int ssign=1;
if(n==0) ssign=0;
for(int i=0;i<n;i++){
sort(Vec.begin(),Vec.end(),Judge);
Node* p;
p=make(Vec[Vec.size()-1],Vec[Vec.size()-2]);
Vec[Vec.size()-2]=p;
Vec.pop_back();
}
Node *q=Vec[0];
if(ssign==1)
DFS(q,0);
else sum2=sum1/8;
printf("%d %d %.1f\n",sum1,sum2,(double)sum1/(double)sum2);
Vec.clear();
}
return 0;
}