POJ - 1521/HDU-1053 Entropy
题意
将每个字符串哈夫曼编码,输出 ASCII 需要位数、哈夫曼编码所需位数、压缩率。
思路
建哈夫曼树,将每个字符编码,然后再对应回去。
代码
注意处理只有一种字母的情况。
POJ 要改一堆乱七八糟的东西。
这个代码可以在 HDU 通过。
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
using PII = pair<int, int>;
const int N = 300;
string s;
unordered_map<char, int> mp;
priority_queue<PII, vector<PII>, greater<PII>> q;
int ch[N][2], ans[N], idx;
void dfs(int u, int x) {
ans[u] = x;
if (ch[u][0]) dfs(ch[u][0], x + 1);
if (ch[u][1]) dfs(ch[u][1], x + 1);
}
void solve() {
mp.clear();
while (q.size()) q.pop();
memset(ch, 0, sizeof(ch));
memset(ans, 0, sizeof(ans));
idx = 128;
int n = s.size();
for (auto x : s) mp[x]++;
for (auto x : mp) q.push({x.second, x.first});
while (q.size() > 1) {
auto a = q.top(); q.pop();
auto b = q.top(); q.pop();
idx++;
ch[idx][0] = a.second;
ch[idx][1] = b.second;
q.push({a.first + b.first, idx});
}
dfs(idx, 0);
for (int i = 0; i < N; i++) ans[i] = max(ans[i], 1);
int sum = 0;
for (auto x : s) sum += ans[x];
cout << 8 * n << ' ' << sum << ' ' << 8.0 * n / sum << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout << setprecision(1) << fixed;
while (cin >> s && s != "END") solve();
return 0;
}