传送门:http://poj.org/problem?id=2001
【分析】找到这个单词的最小前缀,也就是说每个单词独一无二且是最短的前缀,car的前缀不能是,”c“ “ca” ,因为他们在别的单词中也有出现,如果找不到独一无二,就直接输出这个单词,也就是说这个字符所在的节点的sum=1,这个num代表以当前字符串为前缀的单词的数量。
#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
struct tire
{
int sum; //记录这个节点是多少单词的前缀
tire *nex[26];
}*root; //定义一个指针root
void insert(const char *s)
{
tire *p=root;
while(*s!='\0')
{
if(p->nex[*s-'a']==NULL)
{
p->nex[*s-'a']=new tire;
p=p->nex[*s-'a'];
p->sum=1;
for(int i=0;i<26;i++)
p->nex[i]=NULL;
}
else
{
p=p->nex[*s-'a'];
p->sum++;
}
s++;
}
}
void Find(const char *s)
{
tire *p=root;
while(*s!='\0')
{
if(p->nex[*s-'a']==NULL) //次节点不存在,代表这个单词不存在
return ;
p=p->nex[*s-'a']; //存在的话继续便利后面的字母
printf("%c",*s);
if(p->sum==1) //当输出的是此节点为1,这就是这个单词的最小前缀,就停止后面的输出。
return ;
s++;
}
}
int main()
{
root=new tire;
char ch[1000+10][20+5];
for(int i=0;i<26;i++)
{
root->nex[i]=NULL;
root->sum=0;
}
int i=0;
while(gets(ch[i])>0 && ch[i][0]!='\0')
{
insert(ch[i]);
i++;
}
for(int j=0;j<i;j++)
{
printf("%s ",ch[j]);
Find(ch[j]);
printf("\n");
}
return 0;
}
那个这个单词本身就是他自己的前缀,也就是这个节点只出现了一次。