学习了下Trie树,做了道POJ的入门题,留个纪念。
用不同的前缀来表示一大堆字符串,用val数组记录当前前缀出现的次数,出现1就表示这个前缀足以表示当前字符串了。
/*
POJ 2001 Shortest Prefixes
Author: hongrock
10864K 47MS
*/
#include<cstdio>
#include<cstring>
int n;
char str[1000][30];
struct Trie{
int ch[2600000][30];
int val[2600000];
int sz;
void init(){
sz=1;
memset(ch[0], 0, sizeof(ch[0]));
memset(val, 0, sizeof(val));
}
int idx(char c){
return c-'a';
}
void insert(char *s){
int u=0, l=strlen(s);
for(int i=0; i<l; i++){
int c=idx(s[i]);
if(!ch[u][c]){
memset(ch[sz], 0, sizeof(ch[sz]));
ch[u][c]=sz++;
}
u=ch[u][c];
val[u]++;
}
}
void query(char *s){
int u=0, l=strlen(s);
for(int i=0; i<l; i++){
putchar(s[i]);
u = ch[u][idx(s[i])];
if(val[u]==1) break;
}
}
}tr;
int main(){
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
n=0;
tr.init();
while(~scanf("%s", str[n])){
tr.insert(str[n]);
n++;
}
for(int i=0; i<n; i++){
printf("%s ", str[i]);
tr.query(str[i]);
puts("");
}
return 0;
}