暑假- Trie树-(A - Shortest Prefixes)

来源:互联网 发布:js取消绑定事件的方法 编辑:程序博客网 时间:2024/05/23 13:13
/*题意:找出能唯一标示一个字符串的最短前缀,如果找不出,就输出该字符串。 思路: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;}

0 0
原创粉丝点击