暑假- Trie树-(A - Shortest Prefixes)
2015-07-28 09:53
447 查看
/* 题意:找出能唯一标示一个字符串的最短前缀,如果找不出,就输出该字符串。 思路:trie树,所谓唯一最短前缀,就是这个前缀的最后一个字母在之前所有输入的 字符串中只出现过一次(除了找不到的以外),构树的时候每个字母出现一次再所对应的 value++,最后判断这个串的哪个字母是首个出现了一次的字母,则从这个串开始到这个 首次出现了一次的字母结束就是对应的唯一前缀。 */ #include<iostream> #include<cstring> #include<stdio.h> using namespace std; const int MAXN=1005; const int MAXM=100005; struct Node { int value;//标记出现的次数 int child[26];//孩子节点 Node() { value=0; memset(child,0,sizeof(child)); } }; Node trie[MAXM]; int trieN=0; void create(char s[])//构树 { int x=0; for(int i=0;i<strlen(s);i++) { int d=s[i]-'a'; if(trie[x].child[d]==0)//不存在这个孩子节点 { trie[++trieN]=Node();//则构建出一个孩子节点。 trie[x].child[d]=trieN;//孩子节点的下标。 x=trie[x].child[d];//转移节点。 trie[x].value++;//出现次数+1 } else//存在这个孩子节点 { x=trie[x].child[d];//转移节点 trie[x].value++;//出现次数+1 } } } int Search(char s[])//寻找前缀 { int x=0;//出根节点开始 int len=strlen(s); for(int i=0;i<len;i++) { int d=s[i]-'a'; x=trie[x].child[d];//转换子树 if(trie[x].value==1)//如果这个字母只出现一次,则返回这个 { //字母所在的下标 return i; } } return len-1;//否则,不存在唯一前缀,则按要求输出整个串,所以返回这个串的长度 } int main() { char s[MAXN][25]; int t=0; while(scanf("%s",s[t])!=EOF)//输入数据,构树 { create(s[t]); t++; } for(int i=0;i<t;i++) { cout<<s[i]<<' ';//输出原串 int k=Search(s[i]);//寻找唯一前缀的最后一个字母的下标。 for(int j=0;j<=k;j++) { cout<<s[i][j]; } cout<<endl; } return 0; }
相关文章推荐
- 利用Python编写linux自动备份脚本
- linux内核__get_free_page,kmalloc,vmalloc的区别,内核对内存的管理
- Tree's a Crowd
- poj 3469 dinic网络流模板
- linux内核分析——CFS调度器
- FileZilla,WinSCP,VNC,putty,mstsc区别
- 1632 - Alibaba(DP)
- Mysql基本操作
- THC=TERMINAL HANDLING CHARGE,碼頭操作費
- 胡思乱想
- 摘:MD231 gprs模块建立tcp或udp连接,AT命令详细参考
- 数据结构之循环链表
- 【暑期基础2】A HDU 首字母变大写
- HDU 1236 排名
- UINavigationController返回手势失效问题
- maven 常用插件
- csharp:引入app.manifest,程序在win7下以管理员权限运行配置方法
- 地址栏隐藏后面的action名和路径及参数
- matlab更改默认路径
- 读书笔记MoreEffectiveC++(21)