题目描述:
寂寞的PJ终于找到了一个超级可爱的女朋友,他想给她写一封情书,但是他文笔不好,情商又低,只能写写代码才能维持的了生活这个样子 正好PJ可爱的女朋友也是学计算机的,她刚刚学完《计算机导论》,于是PJ灵机一动,打算用二进制写一封情书给她。 因为PJ凑不出来字数,于是PJ想到了这么一种编码方式来延长自己的情书长度: 1、先用英语写好情书,记录出现的英文字符的种类n( 0 < n < = 52),区分大小写。 2、记录每种英文字符出现的频数,按从大到小的次序排好放入队列。如果频数相同,则按字典序。 3、将当前队列中的队首两元素分别作为左右子节点(频数较高的作为左子节点)创建一个父节点,父节点自身的频数值为左右节点的和。并将该父节点放回到队首。 4、重复上述行为直到队列中所有的元素都已经添加到同一棵二叉树上。 5、从根节点开始以深度优先的方式遍历节点,每个节点的左树枝边值记为0,右树枝边值记为1,直到叶节点,按顺序读取树枝的值便是我们所要的该字符的编码,我们称之为PJ编码。 值得注意的是,PJ希望他的情书可读性更强,所以他只转换英文字符,其他字符都不变。并且在输出情书正文之前他要先给他可爱的女孩一个字典以便读懂这篇情书。 情书的长度不超过600字符
输入:
以文件结尾为结束,输入一整篇英文情书,包括空格和回车。
输出:
前n行以从出现频数高到低输出已经出现的英文字符和它对应的PJ编码,以英文冒号和空格隔开。 接下来按原来的格式输出已经转换成PJ编码形式的情书。
输入
I AM PJ
I Love you so much!
CC
输出
o: 000000000000000
C: 000000000000001
I: 00000000000001
u: 0000000000001
A: 000000000001
J: 00000000001
L: 0000000001
M: 000000001
P: 00000001
c: 0000001
e: 000001
h: 00001
m: 0001
s: 001
v: 01
y: 1
00000000000001 000000000001000000001 0000000100000000001
00000000000001 000000000100000000000000001000001 10000000000000000000000000001 001000000000000000 00010000000000001000000100001!
000000000000001000000000000001

就是哈夫曼编码,碰巧数据结构今天讲了,就写了下。
代码写的有点丑,请见谅。
详细解释看代码

#include<bits/stdc++.h>
using namespace std ;
const int MAXN = 600+11;
const int inf = 0x3f3f3f3f;struct Node{int num,lson,rson; // 字符频率 ,当前节点的左孩子的位置,右孩子的位置。char ch; //  节点的字符int id; // 在顺序表中的位置
}node[MAXN*10]; int sz;// node[] 中存的就是树中的所有节点
bool operator <(Node a,Node b){if(a.num!=b.num)return  a.num<b.num;return  a.ch>b.ch;
}map<char,int>cnt;  // 记录字符 频率
map<char,int>::iterator it;
map<char,string>Hash; // 记录字符对应的编码priority_queue<Node>Q; // 优先队列来维护序列的前2最大值 ,其实本题目不用优先队列也可以的,最大+次大 一定是最大。
void Creat(){int pos1,pos2; // 左孩子的位置,右孩子的位置。while(1){pos1=Q.top().id; Q.pop(); if(Q.empty()) break; // 最后肯定会剩下一个节点。pos2=Q.top().id; Q.pop();Node e;e.num=node[pos1].num+node[pos2].num;e.lson=pos1;    e.rson=pos2;e.id=sz;        e.ch='a';  // 这里给父节点的字符 赋值什么都可以不影响  // 创建新父节点node[sz++]=e;   Q.push(node[sz-1]); //插入父节点}
}
void DFS(string s,int now){  //  遍历哈夫曼树得到字符编码if(node[now].lson==-1){  // 说明到了子叶节点Hash[node[now].ch]=s;cout<<node[now].ch<<": "<<s<<endl;return ;}DFS(s+"0",node[now].lson);DFS(s+"1",node[now].rson);
}string str[MAXN];int id; // 记录输入的文档
void Output(){for(int i=0;i<id;i++){for(int j=0;str[i][j];j++){if(str[i][j]>='a'&&str[i][j]<='z'||str[i][j]>='A'&&str[i][j]<='Z')  cout<<Hash[str[i][j]];else cout<<str[i][j];}cout<<endl;}
}
int main(){while(getline(cin,str[id])){for(int i=0;str[id][i];i++) {if(str[id][i]>='a'&&str[id][i]<='z'||str[id][i]>='A'&&str[id][i]<='Z')cnt[str[id][i]]++;}id++;}for(it=cnt.begin();it!=cnt.end();it++){  // 得到子叶节点信息;Node e;e.num=it->second; e.lson=-1; e.rson=-1;e.ch=it->first;   e.id=sz;node[sz++]=e;     Q.push(node[sz-1]);}Creat();     // 创建哈夫曼树DFS("",sz-1); //  遍历哈夫曼树得到字符编码Output();  //输出编码后文章
return 0;
}

【NEUQ】PJ的情书 【哈夫曼树 】相关推荐

  1. 九度oj 题目1172:哈夫曼树

    题目描述: 哈夫曼树,第一行输入一个数n,表示叶结点的个数.需要用这些叶结点生成哈夫曼树,根据哈夫曼树的概念,这些结点有权值,即weight,题目需要输出所有结点的值与权值的乘积之和. 输入: 输入有 ...

  2. Python---哈夫曼树---Huffman Tree

    今天要讲的是天才哈夫曼的哈夫曼编码,这是树形数据结构的一个典型应用. !!!敲黑板!!!哈夫曼树的构建以及编码方式将是我们的学习重点. 老方式,代码+解释,手把手教你Python完成哈夫曼编码的全过程 ...

  3. 优先级队列实现哈夫曼树的编码和译码

    //优先级队列实现的哈夫曼树的编码和译码 #include<iostream> #include<queue> #include<string> using nam ...

  4. HDU1053 Entropy 哈夫曼树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1053 认真读题,别怕题长,此题考查的就是哈夫曼树并求出最小编码值,注意每一次要将数组清0,否则会出错! ...

  5. 数据结构与算法(6-5)二叉树的应用--哈夫曼树与哈夫曼编码

    目录 哈夫曼编码(最优二叉树) 一.优势:缩短电文长度 二.思想: 三.过程: 四.图解实现过程: 五.总代码 哈夫曼编码(最优二叉树) 一.优势:缩短电文长度 二.思想: 获取每个字符出现的频率,用 ...

  6. java振动数据压缩_【数据结构-Java】最佳实践-数据压缩(使用赫夫曼树)

    一.需求 将给出的一段文本,比如 "i like like like java do you like a java" , 根据前面的讲的赫夫曼编码原理,对其进行数据压缩处理 二. ...

  7. 哈夫曼树的java实现_java实现哈夫曼树

    哈夫曼译码,就是将输入的译码还原成对应的字符. 抽象的算法描述:将建立哈夫曼树.实现哈夫曼编码.哈夫曼译码都定义成 子函数的的形式, 然后在主函数中调用它们...... 数据结构课程设计设计题目: 哈 ...

  8. 哈夫曼树的生成及哈夫曼编码

    首先构造哈夫曼树结构体,初始化哈夫曼树的四个无符号整型域,输入文本,统计各个字符的权值,然后构建哈夫曼树,从根到叶子逆向求哈夫曼树的编码. #include"stdio.h" #i ...

  9. 赫夫曼编码(基于赫夫曼树的实现)

    上一篇文章中我们探讨了赫夫曼树的基本原理和构造方式,而赫夫曼编码可以很有效地压缩数据(通常可以节约20%-90%的空间,具体压缩率依赖于数据的特性). 名词:定长编码,边长编码,前缀码(装B用的) 定 ...

最新文章

  1. 22 岁专访库克、B 站 3 天涨粉百万,他将毕设树莓派扫描仪升级,繁星散落在校空!...
  2. Spring Boot 13 之freemarker
  3. 八皇后java_经典八皇后问题:Java语言
  4. 道路运输车辆卫星定位系统JT/T808服务实现和压测
  5. android WebView详解,常见漏洞详解和安全源码(下)
  6. 数据加解密和数据签名验签
  7. Apache-Jmeter监控服务资源
  8. VMware虚拟机安装 windows server 2012 SQL server2012
  9. 个人知识体系思维导图_“知识体系”打得好,学霸孩子跑不了,巧用“思维导图”来帮忙...
  10. 软件工程-构建之法 团队
  11. JDK8下载安装与Win10下Java环境变量配置
  12. matlab中图例的字怎么改,如何在Matlab图形图例中设置自定义标记
  13. golang base64解码碰到的坑
  14. 为什么计算机使用二进制,你知道吗?
  15. 互联网日报 | 吉利汽车完成科创板上市辅导;华为开发者大会9月10日举行;贵州茅台整治“年份酒”乱象...
  16. js 遍历数组及对象属性
  17. ubuntu清理硬盘空间
  18. 随手科技累计用户超3亿 领跑互金App
  19. 关于java集合的查找和删除的小程序
  20. 将Delphi2007的所有dcu打包到一个运行时包中

热门文章

  1. lisp 梯形展开图_斜截圆柱件钣金展开图的AutoCAD二次开发
  2. 图鉴|春节怼亲戚指南(2020版)
  3. 备战面试日记(2.4) - (JVM.GC算法)
  4. 808 Lab虚拟插件:Sample Science 808 Lab for Mac
  5. 视频插件VideoJS5介绍
  6. 米家APP获取小米、绿米网关key的方法(5.6.81版本)(2020_05_15)
  7. S5700交换机出现discarding丢弃错误处理办法
  8. FTP bin和ascii的区别
  9. {typedir} {style} {tid} {aid} 分别是什么意思?
  10. Java hashCode详解