我以为像a、aa这样的输入应该是没有输出的,结果还是要输出aa。
建树的时候就是常规建树,不过查找的时候要做一些变形:对于一个单词,从第一位检查有没有单词是它的前缀,如果有的话,再去检查它的后半部分是不是一个独立的单词,要满足这两次查找才能输出。
老是从自己写的字典树里面闻出一种山寨的味道。
#include<stdio.h>
#include<string.h>
#include<malloc.h>
#define N 50005
char s[N][30];
struct node
{
node *a[26];
int flag;
int id;
};
node *root;
void InsertTree(char *ss)
{
int i,ln;
node *cur,*s;
ln=strlen(ss);
cur=root;
for(i=0;i<ln;i++)
{
int temp;
temp=ss[i]-'a';
if(i==ln-1)
{
if(cur->a[temp]!=NULL)
cur->a[temp]->flag=1;
else
{
s=(node *)malloc(sizeof(node));
memset(s->a,0,sizeof(s->a));
s->flag=1;
s->id=-1;
cur->a[temp]=s;
}
}
else if(cur->a[temp]!=NULL)
cur=cur->a[temp];
else
{
s=(node *)malloc(sizeof(node));
memset(s->a,0,sizeof(s->a));
s->id=-1;
s->flag=0;
cur->a[temp]=s;
cur=s;
}
}
return ;
}
int FindTree(char *s,int flag,int k)
{
int i,ln;
node *cur;
cur=root;
ln=strlen(s);
if(!flag)
{
for(i=0;i<ln;i++)
{
int temp=s[i]-'a';
if(cur->a[temp]!=NULL)
{
if(cur->a[temp]->flag)
{
cur->a[temp]->id=k;
if(FindTree(s+i+1,1,k)==2)
return 1;
}
cur=cur->a[temp];
}
else
return 0;
}
}
else
{
for(i=0;i<ln;i++)
{
int temp=s[i]-'a';
if(i==ln-1)
{
if(cur->a[temp]!=NULL/*&&cur->a[temp]->id!=k*/&&cur->a[temp]->flag)
return 2;
else
return 0;
}
else if(cur->a[temp]!=NULL)
cur=cur->a[temp];
else
return 0;
}
}
return flag;
}
int main()
{
int k=0;
root=(node *)malloc(sizeof(node));
memset(root->a,0,sizeof(root->a));
root->flag=0;
root->id=-1;
while(gets(s[k]))
{
InsertTree(s[k]);
k++;
}
int i;
for(i=0;i<k;i++)
{
if(FindTree(s[i],0,i))
puts(s[i]);
}
return 0;
}