Greedy——HDUOJ 1553 - Entropy(哈夫曼树求解)

#原题

  • Problem Description

哈夫曼解释…(内容过多)

  • Sample Input

AAAAABCD
THE_CAT_IN_THE_HAT
END

  • Sample Output

64 13 4.9
144 51 2.8

###解题思路:
这里写图片描述
####首先,得理解哈夫曼树的原理和使用的价值。。。。

题目大概意思就是:
怎么通过算法让字符串存储的空间大幅度的减少。
####贪心:
一般一个字符用8bit存储,所以一个字符串(10个字符)就得80位的存储空间。
通过哈夫曼树:用01二进制去表示每一个字符,对于出现频率多的字符则01数量少,对于出现频率少的则01数量就多了。
构建完后,如上图2-1©所示,对于C字符,出现的次数是5(也就是说需要用到5次C,可以理解为M到C需要经过5次,即T->M->C需要经过5次,因为C表示’10’(B),所以一共有5个’10’来存储C,即10bit)
可以把所有非叶子节点的权值加起来,就是所有字符需要存储的空间。
用哈夫曼树算法构建成数的种类有很多种,但总结果都是相同的。

###代码:

#include <iostream>
#include <string>
#include <queue>
#include <functional>
using namespace std;
int main()
{
	string test;
	int letterNum[27], sum;
	priority_queue<int, vector<int>, greater<>> HuffmanTree;//优先队列,每次输出堆顶(小顶堆)
	while (cin >> test)
	{
		if (!test.compare("END"))
			break;
		while (!HuffmanTree.empty())HuffmanTree.pop();
		memset(letterNum, 0, sizeof(letterNum));
		sum = 0;
		for (const char&t : test)//计算每个字母出现的次数
		{
			if (t == '_')letterNum[26]++;//空格用_表示
			else letterNum[t - 'A']++;
		}
		for (const int&t : letterNum)//将每个字母出现的次数存入堆中
			if (t != 0)HuffmanTree.emplace(t);
		if (HuffmanTree.size() == 1)sum = test.size();//如果只有一种字母,则字符串长度就是该字符串的存储空间
		while (HuffmanTree.size() > 1)
		{
			int temp = 0;
			for (int i = 0; i < 2; i++)//构建哈夫曼树
			{//每次都将最小的两个数提取出来构建
				temp += HuffmanTree.top();
				HuffmanTree.pop();
			}
			sum += temp;
			HuffmanTree.emplace(temp);
		}
		printf("%d %d %.1f\n", test.size() * 8, sum, test.size() * 8.0 / sum);
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值