偷懒的写法,输入是随便一串字符串,比如“aaaaabsdfkhsdaa”,依次求字母出现概率,然后计算编码。
/***********************************************\
|Author: Messyidea
|Created Time: 2014-5-9 18:54:25
|File Name: hufman.cpp
|Description:
\***********************************************/
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <string>
#include <cstring>
#include <algorithm>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
using namespace std;
struct node{
string c;
double p; //possibility
bool operator < (node a)const{
return p>a.p;
}
};
priority_queue<node> pq;
map<string,int> ma;
map<string,string> mb;
int main() {
freopen("input2.txt","r",stdin);
string s;
cin>>s;
//cout<<s<<endl;
int total = s.length();
for(int i = 0;i<total;++i){ //计算每个字符出现的次数
//cout<<s[i]<<endl;
string ss = "";
ss += s[i];
ma[ss] ++;
}
map <string,int>::iterator it = ma.begin();
while(it!=ma.end()){ //计算每个字符出现的概率
node tp;
tp.c = it->first;
tp.p = (it->second)*1.0/total;
//cout<<tp.c<<" "<<tp.p<<endl;
pq.push(tp);
it++;
}
while(pq.size()>=2){ //编码
node t1,t2,t3;
t1 = pq.top();
pq.pop();
t2 = pq.top();
pq.pop();
//cout<<t1.p<<" "<<t2.p<<endl;
t3.c = t1.c + t2.c;
for(int i=0;i<t1.c.length();++i){
string ss = "";
ss += t1.c[i];
mb[ss] += "0";
//cout<<ss<<endl;
}
for(int i=0;i<t2.c.length();++i){
string ss = "";
ss += t2.c[i];
mb[ss] += "1";
}
t3.p = t1.p + t2.p;
pq.push(t3);
}
map<string,string>::iterator it2 = mb.begin();
while(it2!=mb.end()){ //逆序并输出
reverse((it2->second).begin(),(it2->second).end());
cout<<it2->first<<" "<<it2->second<<endl;
it2++;
}
return 0;
}