POJ 2503 - 字典树再解
来源:互联网 发布:文言文字典软件 编辑:程序博客网 时间:2024/05/18 20:36
1.Question:
题意:
有不超过10w个字典序列,每个字典序列中都是两个字符串,第一个字符串是英文,第二个字符串是对应的一门不知道什么语言
现在要求我们尽可能快速的建立映射,是的我们根据输入的外语可以快速的查找到对应的英语
每个单词的长度不超过10,全部都是小写(简化了问题)
输入样例和解释:
dog ogdaycat atcaypig igpayfroot ootfrayloops oopslayatcayittenkayoopslay
第一个序列代表我们的字典序列
之后的一个空行之后我们开始执行查找操作,输入一直执行到文件的末尾
2.Solution:
本题的思路很多,因为是查找类的题目:
通解有:字典树,快排+二分,字符串哈希
本文只针对字典树的解法,快排和哈希我另外再写解法
对于字典树,如果还没有了解,欢迎访问我的博客:lantian的字典树总结
首先对于本题来说,因为是OJ上的题目,我们对速度是要非常的小心的,所以这里我们摒弃查找速度相对较慢的双链法实现的字典树,我们采用类似B树的形式构建多键字典树
字典树的节点内容:
typedef struct node{char key; //存储当前的键位 struct node* nextp[27]; //子指针 char* data; //存储字典键值 bool isleaf; //判断域是否是叶子节点bool isphrase; //判断以当前键结束的词是否出现过 }point;这里的isphrase是非常的有必要的,在总结中我已经提到了,我们的字典树采用的是公共前缀的压缩处理方式所以说我们真的很有必要判断当前的节点是不是一个单词的末尾
PS:在这里为了节约内存我稍微做了点优化,我将存储字符串的变量没有设置成数组,我设置成了字符指针,对于非叶子节点只占用一个字节的内存,只有对于叶子节点才会保存长的字符串
3.Code:
相对高效存储的(因为考虑的建树的时间,字典树的速度会稍微的慢于字符串哈希)哈希算法而言,我们的字典树是稍微,慢了的,但是还算是非常的高效
/*Problem: 2503User: lantianheyeqiMemory: 20760KTime: 516MSLanguage: C++Result: Accepted*/#include"iostream"#include"cstdio"#include"cstring"#include"cstdlib"using namespace std;typedef struct node{char key; //存储当前的键位 struct node* nextp[27]; //子指针 char* data; //存储字典键值 bool isleaf; //判断域是否是叶子节点bool isphrase; //判断以当前键结束的词是否出现过 }point;point root; //根节点,根节点没有键值 int number; //节点总数char english[13];char foreign[13];void initpoint(point& x,char key) //初始化节点 {x.key=key;for(int i=0;i<27;i++) x.nextp[i]=NULL;x.data=NULL;x.isleaf=true;x.isphrase=false;}void insert(){point* help=&root; char* now=foreign;while(*now!='\0'){if(help->nextp[(*now-'a')]!=NULL) help=help->nextp[(*now-'a')];else{point* p=new point;initpoint(*p,*now);if(*(now+1)!='\0') p->isleaf=false; //强制转化非叶子节点 else {p->isphrase=true; //强制转化成单词节点p->data=(char*)malloc(sizeof(char)*12);strcpy(p->data,english);} help->nextp[(*now-'a')]=p;help=p;}now++;}}void find(){point* p=&root;char* now=foreign;while(*now!='\0'){if(p==NULL) break;p=p->nextp[(*now-'a')];now++;}if(p==NULL) printf("eh\n");else printf("%s\n",p->data);}int main(){char ppp[30];initpoint(root,'#');while(gets(ppp) && ppp[0]!='\0'){sscanf(ppp,"%s %s",&english,foreign);insert(); //插入操作number++; memset(english,0,sizeof(english));memset(foreign,0,sizeof(foreign));}while(gets(foreign)){find();memset(foreign,0,sizeof(foreign));}return 0;}
1 0
- POJ 2503 - 字典树再解
- poj 2503 字典树
- POJ 2503 字典树
- poj-2503 字典树
- poj 2503(字典树)
- poj 2503 Babelfish(字典树)
- poj 2503 Babelfish 字典树
- poj 2503 Babelfish(字典树)
- POJ 2503 Babelfish(字典树)
- poj-2503-Babelfish-字典树
- poj 2503 Babelfish(字典树)
- POJ 2503 - Babelfish(字典树)
- poj 2503 Babelfish 字典树
- POJ 2503-Babelfish【字典树】
- POJ 2503 构造字典 翻译单词 使用字典树
- POJ 2503 Babelfish 字典树应用
- POJ 2503 Babelfish(字典树Trie)
- POJ - 2503 Babelfish 字典树做法
- laravel 四 路由高级
- javascript中return、return true、return false的区别;
- Ubuntu16.04lTS安装QQ在处理时有错误发生: wine-qqintl
- ssh免密码登录配置方法,(图示加命令)
- js获取移动端设备宽高
- POJ 2503 - 字典树再解
- 导出word net
- Docker容器内多进程管理(二)-Monit
- 揭开斐讯免费路由器通过京东热销的幕后真相
- 坚固环球:坚固环球双11 活动上线 特享iPhone7三重大礼
- UIViewController的View显示在导航栏下面如何解决?
- 403 forbidden解决办法
- spark 问题
- grep参数