poj1521

这么大长段的英文看懂了也是很不容易。感谢这学期的密码学让我对entropy有了点印象,对理解题目起到了很大的帮助。
所以啊,书都不是白念的,课都不是白听的~

言归正传。先上题目链接 点击打开链接
这道题刚开始看的时候理解的一塌糊涂,因为上一次学哈夫曼大概是一年前的算法课了,再上一次是一年半前的数据结构,再上一次是两年前的离散数学,太久远了。

但是还好认真学过看着看着就想起来,哎,好像学过一个什么算法和这个差不多,咦,好像叫哈夫曼树!翻开算法教材,瞬间想起来了。
知道了原理,还是不会写,因为刚开始刷算法题嘛,肯定需要一个过程。上网搜搜答案,发现一个很重要的思想,就是树除了根以外所有节点权值的和就可以反映编码总长度,也是,每个节点都是之前所有子孙叶子节点权值的和,而每个叶子节点对应的元素对应编码长度又都是对应的树层数。想想很好理解。

还是那句话。虽然借鉴了网上的代码思想,但是程序都是自己写出来的。相信自己慢慢会变强的!
下面上代码~
#include<iostream>
#include<queue>
#include<string>
#include<map>
using namespace std;
int main(){
	priority_queue<int,vector<int>,greater<int> > q;//优先队列,默认由大到小排序,这种写法可以改为由小到大排序 
	map<char,int>f;//字符对应频率建立映射 
	map<char,int>::iterator iter;
	string s;
	cin>>s;// 
	while(s!="END"){
		for(int i=0;i<s.length();i++){
			iter=f.find(s[i]);
			if(iter==f.end()){
				f[s[i]]=1;//初始化 
			}
			else{
				f[s[i]]++;//再次出现 
			}
		}
		iter=f.begin();
		while(iter!=f.end()){//将次数对应写入map 
			q.push(iter->second);
			iter++;
		}
		//queue<int>::iterator iter1=q.begin();queue不能遍历 
		int m,n,sum=0;
		if(q.size()==1){//只有一个字母 
			sum=q.top();
		}
		while(q.size()>1){
			m=q.top();q.pop();//pop没有返回值 
			n=q.top();q.pop();
			q.push(m+n);//建立新的节点 
			sum+=(m+n);//累加的思路 
		}
		q.pop();//清除队列 
		f.clear();//清除映射 
		printf("%d %d %.1f\n",s.length()*8,sum,(double)((double)(s.length()*8)/sum));// 
		
		cin>>s;
	}
    return 0;
} 
遇到的问题及总结如下:
1.priority_queue 这个东西以前没有见过。

2.scanf是不能接收string的。
3.queue是不能遍历的。

4.queue的pop没有返回值。要访问只能先用top。
5.输入多组数据的情形一定要考虑到相关容器的清空,变量的初始化。

6.printf限制小数点的格式要注意,而且要注意数据类型的转换!尤其是除法!
加油加油~
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值