贪心、哈夫曼编码——Entropy POJ - 1521

https://vjudge.net/problem/POJ-1521
利用哈夫曼的思想,可以直接计算编码的总长度,跳过编码的过程。
哈夫曼编码介绍

#include<iostream>
#include<queue>
#include<string>
#include<algorithm>
//#include<vector>并不需要

using namespace std;

int main(void) {
	string s;
	priority_queue< int, vector< int >, greater <int> > Q;
	//这种写法表示升序排序,降序是less

	while(getline(cin, s) && s != "END"){
		int t = 1;
		sort(s.begin(), s.end());//对字符串排序,方便计算字母频次
		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 ans = 0;
		if (Q.size() == 1) ans = Q.top();//哈夫曼无法处理一种字符,此时长度就是它的频次
		while (Q.size() > 1) {//因为要连续取出两个元素,所以不能用!Q.empty()
			int a = Q.top(); Q.pop();
			int b = Q.top(); Q.pop();
		//	printf("%d + %d\n", a, b);
			Q.push(a + b);
			ans += (a + b);
		}
		Q.pop();
		int ans2 = s.length() * 8;
		printf("%d %d %.1lf\n", ans2, ans, double(ans2) / ans);
	}



	return 0;
}
posted @ 2021-11-17 17:05  tsrigo  阅读(27)  评论(0)    收藏  举报