题意:给你一部分单词,让你找出所有这样的单词:a+b=c,就是一个单词,由另外两个单词串联而成
解题思路:先输入全部单词,构建一棵tire树,然后枚举所有单词,对单词进行查找,查找过程中经过的单词节点记录下来,(已经确定有一个单词了,寻找另一个单词是否存在)然后从这个节点再重新搜(树根开始),如果另一个单词也存在,则符合要求
最后按照字典序排下序输出即可
sample:
a
ahat
hat
hatword
hziee
word
构建了这样一棵tire树,我们搜索下hatword,搜索过程中发现hat是一个单词,然后我们从根开始搜索word是否存在,如果存在,就符合,具体实现请看代码
#include<stdio.h>
#include<string.h>
#include<vector>
#include<stdlib.h>
#define val 50005
using namespace std;
int cmp(const void *a,const void*b)
{
return strcmp((char*)a,(char *)b);
}
struct Dictree
{
bool end;
Dictree *next[26];
}*root;
vector<int> pos;//记录可能的节点
void create_tree();
void insert(char *);//构建tire树
void search(char *);//查找节点
bool find(char *);//查找另一个单词
char s[val][20];
char ans[val][20];
int main()
{
int index=0,v=0;
int i,j,k;
create_tree();
while(scanf("%s",s[index++])!=EOF)
insert(s[index-1]);
for(i=0;i<index;i++)
{
pos.clear();
search(s[i]);
for(j=0;j<pos.size();j++)
{
if(find(s[i]+pos[j])==true)
{
strcpy(ans[v++],s[i]);
break;
}
}
}
qsort(ans,v,sizeof(ans[0]),cmp);
for(i=0;i<v;i++)
puts(ans[i]);
return 0;
}
void insert(char *s)
{
int i,j;
Dictree *p,*t;
p=root;
for(i=0;s[i];i++)
{
if(p->next[s[i]-'a']==NULL)
{
t=(Dictree*)malloc(sizeof(Dictree));
t->end=false;
memset(t->next,NULL,sizeof(t->next));
p->next[s[i]-'a']=t;
}
p=p->next[s[i]-'a'];
}
p->end=true;
}
void create_tree()
{
root=(Dictree*)malloc(sizeof(Dictree));
root->end=false;
memset(root->next,NULL,sizeof(root->next));
}
void search(char*s)
{
int i;
Dictree *p=root;
for(i=0;s[i+1];i++)
{
p=p->next[s[i]-'a'];
if(p->end) pos.push_back(i+1);
}
}
bool find(char *s)
{
int i;
Dictree *p=root;
for(i=0;s[i];i++)
{
if(p->next[s[i]-'a']==NULL)
return false;
else p=p->next[s[i]-'a'];
}
if(p->end) return true;
else return false;
}