[POJ1521]Huffman编码
来源:互联网 发布:菜刀三国杀淘宝 编辑:程序博客网 时间:2024/06/13 20:44
[POJ1521]Huffman编码
时间限制: 1 Sec 内存限制: 128 MB题目描述
输入一个字符串,长度不超过100,仅由大写字母和下划分组成。求用最好的字符编码方式,令总长度最小。
输入
多组数据,每组数据在一行上输入一个字符串,格式如前所述
当遇到END时,表示输入结束
输出
对应每个输入,在一行上输出3个信息:首先是每个字母按固定长度8bit编码,字符串的总长度,然后是按最优编码的总长度,最后是前者对后者的比率,保留1位小数。
样例输入
AAAAABCDTHE_CAT_IN_THE_HATEND
样例输出
64 13 4.9144 51 2.8
这道题思路就是构造哈夫曼树,然后从根一遍dfs扫出叶节点深度(就
是每个字符的编码长度)最后按照算出来的编码算原字符串的长度。哈夫曼编码:
普通的unsigned char最大255 长度为2^8 二进制下长度8位
传输时数据量较大。哈夫曼编码按照每个字符的出现频率为字符编出长
1-8位(二进制)的编码,出现频率越高的字符编码越短,能有效缩减
传输信息长度,而且不会出现歧义。
哈夫曼树:
哈夫曼树属于2×树。其中,每一个叶节点都代表一个字符,向左延伸
的边代表‘0’,向右延伸的边代表1
从根节点出发到叶节点的01路径就代表此叶节点字符的哈夫曼编码
构造哈夫曼树:
先生成出现字母的叶节点,吧节点的权重设为字母出现次数,压入大根
优先队列,每次取出两个节点(权重最小),新建一个节点作为这两个
节点的父亲(新节点不能表示什么,只起结构作用),新节点权重为儿
子节点之和。把新节点压入优先队列。如此反复,到队列中只有一个节
点时结束。此时队列中节点为根。
最后从根节点dfs标记叶节点深度,深度就是0-1串编码长度。最后在扫
原字符串累和即可。
代码也不长,但是从昨天一直wa,一开始就想到字符串有只有一个相同
字符的情况,随手就特判打了puts("8 1 8.0"); 然后接着wa,之后再
网上找到正确代码对拍1000+组数据才发现我的程序被"QQ"终结了。
才发现是特判错误,改成printf("%d %d 8.0\n",len*8,len)就AC了
= = 这也算犯二吧
#include<cstdio>#include<cstring>#include<queue>using namespace std;char str[120];int cnts[27];bool cmp(int a,int b){ return cnts[a]<cnts[b];}int prs(char c){ if(c>='A'&&c<='Z')c-='A'-1; else c=0; return c;}char unp(int i){ if(i>=1)i+='A'-1; else i='_'; return (char)i;}struct Node{ int l,r; Node(){}}nodes[600];int tot=27;struct mpair{ int a,b; mpair(){} mpair(int aa,int bb){a=aa,b=bb;} bool operator<(mpair an)const{ return b>an.b; }};/*int fa[600];int root(int a){ if(fa[a])return fa[a]=root(fa[a]); return a;}*/int lens[27];void dfs(int u,int depth){ if(u<=26){lens[u]=depth;return;} else dfs(nodes[u].l,depth+1),dfs(nodes[u].r,depth+1);}void init(){ tot=27; memset(nodes,0,sizeof nodes); memset(cnts,0,sizeof cnts); memset(lens,0,sizeof lens);}int main(){ while(~scanf("%s",str)){ if(!strcmp(str,"END"))return 0; init(); int len=strlen(str); for(int i=0;i<len;i++)cnts[str[i]=prs(str[i])]++; priority_queue<mpair> que; int ecnt=0; for(int i=0;i<=26;i++)if(cnts[i]) que.push(mpair(i,cnts[i])),ecnt++; if(ecnt==1){ printf("%d %d 8.0\n",len*8,len); continue; } while(ecnt>1){ mpair a,b; a=que.top(); que.pop(); b=que.top(); que.pop(); //printf("union:%d(%d) %d(%d)\n",a.a,a.b,b.a,b.b); nodes[tot].l=a.a; nodes[tot].r=b.a; que.push(mpair(tot++,a.b+b.b)); ecnt--; } dfs(que.top().a,0); int length=0; for(int i=0;i<len;i++)length+=lens[str[i]]; printf("%d %d %0.1lf\n",len*8,length,(double)(len*8)/length); }}
3 0
- [POJ1521]Huffman编码
- #POJ1521#Huffman编码
- [POJ1521]Huffman编码
- ZOJ1117 POJ1521 HDU1053 Huffman编码
- 【POJ1521】【HDU1053】Entropy 哈夫曼(Huffman)编码
- poj1521(huffman)
- poj1521 huffman
- poj1521 (huffman +优先队列)
- poj1521 求赫夫曼编码长度
- poj1521
- poj1521
- POJ1521
- poj1521
- Huffman树&&Huffman编码
- huffman编码
- huffman编码
- HUFFMAN 编码
- Huffman编码
- 从 0 搭建 DokuWiki
- 树莓派通过邮件上报实时IP,随时随地远程登录树莓派
- spring的事务配置与隔离级别
- js-分享功能(qq,微信,微博)
- js控制video的播放和暂停
- [POJ1521]Huffman编码
- uploadify.js
- shareSDK导入的常见错误及解决方法
- soap-ws 获取wsdl中所有方法 (一)
- [e袋购]电商为物业开拓新出口
- iOS开发中的一些常用方法
- Android 圆角fraagment的实现
- 实现杂记(27):解决在onCreate()过程中获取View的width和Height为0的4种方法
- linux curl参数详解