Haffman编码(haffman树)
2016-03-01 13:16
435 查看
Haffman编码
时间限制:1000 ms | 内存限制:65535 KB难度:3
描述
哈弗曼编码大家一定很熟悉吧(不熟悉也没关系,自己查去。。。)。现在给你一串字符以及它们所对应的权值,让你构造哈弗曼树,从而确定每个字符的哈弗曼编码。当然,这里有一些小规定:
1.规定哈弗曼树的左子树编码为0,右子树编码为1;
2.若两个字符权值相同,则ASCII码值小的字符为左孩子,大的为右孩子;
3.创建的新节点所代表的字符与它的左孩子的字符相同;
4.所有字符为ASCII码表上32-96之间的字符(即“ ”到“`”之间的字符)。
输入输入包含多组数据(不超过100组) 每组数据第一行一个整数n,表示字符个数。接下来n行,每行有一个字符ch和一个整数weight,表示字符ch所对应的权值,中间用空格隔开。 输入数据保证每组测试数据的字符不会重复。输出对于每组测试数据,按照输入顺序输出相应的字符以及它们的哈弗曼编码结果,具体格式见样例。样例输入
3 a 10 b 5 c 8 4 a 1 b 1 c 1 d 1
样例输出
a:0 b:10 c:11 a:00 b:01 c:10 d:11 题解:让求一颗哈夫曼树,哈夫曼树是先找到最小的两个建一个根节点,这个根节点的权值为两个小的权值和; 加入这个新节点,重新找;用优先队列实现;其根节点即为元素在树中的位置; 代码:
#include<cstdio> #include<iostream> #include<cmath> #include<algorithm> #include<cstring> #include<queue> using namespace std; const int INF=0x3f3f3f3f; #define mem(x,y) memset(x,y,sizeof(x)) #define SI(x) scanf("%d",&x) #define PI(x) printf("%d",x) typedef long long LL; string ans[300]; char c[310]; struct Node{ char c; int v; Node *l,*r; Node(){ l=r=NULL; } Node(char ch,int vv,Node *ll=NULL,Node *rr=NULL){ c=ch;v=vv;l=ll;r=rr; } bool operator < (const Node &b) const{ if(v!=b.v)return v>b.v; else return c>b.c; } }; Node e[300]; void dfs(Node *now,string s){ if(now->l==NULL&&now->r==NULL){ ans[int(now->c)]=s;return; } if(now->l!=NULL)dfs(now->l,s+'0'); if(now->r!=NULL)dfs(now->r,s+'1'); return ; } int main(){ int N,v; //char s[2]; while(~SI(N)){ if(N==0)continue; for(int i=0;i<300;i++)e[i].l=e[i].r=NULL; priority_queue<Node>Q; getchar(); for(int i=0;i<N;i++){ scanf("%c %d",&c[i],&v);getchar();//这里不这样输入就错了 //c[i]=s[0]; Q.push(Node(c[i],v)); } int tp=0; while(Q.size()>1){ e[tp++]=Q.top(); Q.pop(); e[tp++]=Q.top(); Q.pop(); Q.push(Node(e[tp-2].c,e[tp-2].v+e[tp-1].v,&e[tp-2],&e[tp-1])); //Node(e[tp-2].c这样插是为了当和等于下一个的v的时候排在前边; //为什么要再开一个数组e:为了保持队列里面元素的l,r对应关系; } Node ss; ss=Q.top(); //printf("%c %d\n",ss.c,ss.v); dfs(&ss,""); //printf("****"); for(int i=0;i<N;i++){ //printf("%c:%s\n",c[i],ans[int(c[i])].c_str()); cout<<c[i]<<":"<<ans[int(c[i])]<<endl; } } return 0; }
相关文章推荐
- 如何高效地输出iOS和Android标注和切图
- 手势(Gesture)
- NSString从字符串开头截取到指定字符的位置
- oracle冷备及恢复
- 1.1.3 探索你的集群(Exploring Your Cluster)
- bzoj 1050: [HAOI2006]旅行comf 并查集
- Keepalive+Amoeba+Mysql 实现高可用,负载均衡及读写分离
- Weblogic在Linux上创建域
- awk 统计
- 面向对象设计原则之依赖注入原则(DIP)
- Android多屏幕适配
- java高级面试题1
- 文章标题--再识HTML5
- Android 设置DrawableRight和DrawableLeft 点击事件
- codeforces633D Fibonacci-ish map容器
- JAVA中私有属性private能被子类继承吗?
- poj 2686 Traveling by Stagecoach TSP 图 状压dp
- 将博客搬至CSDN
- 顺序容器5 访问元素
- LAMP及LNMP测试环境快速构建(yum版)