POJ - 1521 Entropy (Huffman编码)

题目大意:
输入一行的字符串, 分别用8bit-ASCII编码和Huffman编码, 求出编码后所占的空间以及压缩比(ASC/Huffman)

思路: 利用优先队列实现Huffman编码, 其中并不需要建树, 只需要求出每个字符出现的频数, 借助优先队列求出根节点的频次.
Huffman编码的实现过程类似于经典题 "合并果子".
Huffman编码的本质是贪心的思想, 出现频次多的放在树的上层, 少的放在下层, 以此作为贪心的策略, 即可得到最优的Huffman编码.
同时注意, 对于本题有一个需要注意的点, 对于只有相同字符的字符串需要特判一下, Huffman树编码前提条件是需要多字符的树.
完整代码如下:

/*
 * @Author: Hellcat
 * @Date: 2020-03-28 11:13:41
 */
#include <iostream>
#include <cstdio>
#include <queue>
#include <algorithm>
#include <string>
using namespace std;

int main() {
    string s;
    priority_queue<int, vector<int>, greater<int> > q;
    while(getline(cin, s) && s != "END") {
        while(q.size()) q.pop();
        int Asc = s.length() * 8;
        sort(s.begin(), s.end());
        int t = 1;
        for(int i = 1; i < s.length(); i++) {
            if(s[i] != s[i-1]) {
                q.push(t); t = 1;
            }
            else t++;
        }
        q.push(t);
        int Huff = 0;
        if(q.size() == 1) Huff = t; // 只出现一种字符时特判
        while(q.size() > 1) {
            int a = q.top(); q.pop();
            int b = q.top(); q.pop();
            q.push(a+b);
            Huff += (a+b);
        }
        q.pop();
        printf("%d %d %.1f\n", Asc, Huff, (double)Asc/Huff*1.0);
    }
}
posted @ 2020-05-18 11:18  hellcat9  阅读(173)  评论(0编辑  收藏  举报