标准trie字典树
全局指针变量默认赋值NULL
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int MAX=26;
char str[1000][21],res[1000][21];
struct node{
struct node *next[MAX]; //字母分支
int flag; //字母出线过的次数统计
}node;
struct node *root; //根节点
void inset_tree(char *str) //插入字符串
{
int ans,i,len;
struct node *p,*q;
p=root; //p先指向根节点
len=strlen(str);
for(i=0;i<len;i++){
ans=str[i]-'a'; //每一个字母的字母编号
if(p->next[ans]!=NULL) //如果非空
{
p=p->next[ans]; //p指向该字母节点
p->flag++; //该字母出现过的次数加1
}
else{
q=(struct node*)calloc(1,sizeof(node)); //创建新节点
p->next[ans]=q; //q赋给该节点
p=q; //p指向该节点
p->flag=1; //节点数为1
}
}
}
void find(char *str,char *res) //查找
{
int len,ans,i;
struct node *p;
p=root;
len=strlen(str);
for(i=0;i<len;i++){
ans=str[i]-'a';
p=p->next[ans]; //p指向该字母节点
res[i]=str[i]; //该字母赋给结果数组
if(p->flag==1) //如果该字母是这个字符串所独有的
{
res[++i]='\0'; //查找完成
return ;
}
}
}
int main(){
int n=0,i;
root=(struct node *)calloc(1,sizeof(node));
while(scanf("%s",str[n])!=EOF) //插入输入的每一个字符串
{
inset_tree(str[n]);
n++;
}
for(i=0;i<n;i++) //查找每一个字符串的最短有效前缀
find(str[i],res[i]);
for(i=0;i<n;i++)
printf("%s %s\n",str[i],res[i]);
return 0;
}