Question
请设计一个算法,给一个字符串进行二进制编码,使得编码后字符串的长度最短。
Algorithm
哈夫曼编码,权为各个字符出现的频率,再借助小根堆计算。
result=词频1*深度1+词频2*深度2…
词频可以借助哈希表统计,而深度可以通过小根堆来实现
比如:
MT-TECH-TEAM
哈希表统计完字符出现的次数后,为1,1,1,2,2,2,3
找出权最小的2个(1,1),生成新的结点2(重复此步骤)
1,2,2,2,2,3(res=2)
2,2,2,3,3(res=2+3=5)
2,3,3,4(res=5+4=9)
3,4,5(res=9+5=14)
5,7(res=14+7=21)
12(res=21+12=33)
这样做的依据是可以计算每个权在树中的深度。
Code
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<map>
#include<functional>
using namespace std;
int main(){
string str;
while (cin >> str){
map<char, int> hash;
for (int i = 0; i<str.size(); i++){
hash[str[i]]++;
}
map<char, int>::iterator it = hash.begin();
priority_queue<int, vector<int>, greater<int>> q;
int cnt = 0;
for (; it != hash.end(); it++){
q.push(it->second);
cnt++;
}
int x1, x2;
int res = 0;
while (--cnt > 0){
x1 = q.top(); q.pop();
x2 = q.top(); q.pop();
res += x1 + x2;
q.push(x1 + x2);
}
cout << res << endl;
}
return 0;
}