题目大意:查找单词表中的一个单词能否由表中另外两个单词连接而成。
思路: 从字典树中搜前一半,然后判断另一半是否也在字典树内。
#include"stdio.h"
#include"string.h"
#include"math.h"
#include"stdlib.h"
#include"algorithm"
#include"iostream"
using namespace std;
char v[50000][123];
struct trie
{
int mark;
trie *next[27];
};
trie *root;
void init(char *a) //建树
{
int i;
trie *p=root,*q;
for(i=0;a[i];i++)
{
int k=a[i]-'a';
if(p->next[k]==NULL)
{
q=(trie *)malloc(sizeof(trie));
q->mark=0;
for(int j=0;j<26;j++) q->next[j]=NULL;
p->next[k]=q;
p=q;
}
else p=p->next[k];
}
p->mark=1;
}
int judge(char *a)
{
trie *p=root;
int i;
for(i=0;a[i];i++)
{
int k=a[i]-'a';
p=p->next[k];
if(p==NULL) return 0;
}
if(p->mark==1) return 1;
return 0;
}
int finde(char *a) //查找
{
trie *p=root;
int i;
for(i=0;a[i];i++)
{
int k=a[i]-'a';
p=p->next[k];
if(p->mark==1&&judge(a+i+1)) //p-mark==1代表到当前位置构成一个单词,judge判断另一部分是否也在单词表内
return 1;
}
return 0;
}
int main()
{
int i,k;
root=(trie *)malloc(sizeof(trie));
for(i=0;i<26;i++) root->next[i]=NULL;
k=0;
while(scanf("%s",v[k])!=-1)
{
init(v[k++]);
}
for(i=0;i<k;i++)
{
if(finde(v[i]))
puts(v[i]);
}
}