解题思路:
判断给出的单词是否恰好由另外两个单词组成,用栈保存每个子字符串的节点,从这个节点出发判断剩下的字符串是否在字典树中即可。
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <map>
#include <stack>
#include <set>
using namespace std;
const int MAXN = 50000 + 10;
typedef struct Trie_Node
{
bool isword;
struct Trie_Node *next[26];
}Trie;
void insert(Trie *root, char *word)
{
Trie *p = root;
int i = 0;
while(word[i] != '\0')
{
if(p->next[word[i]-'a'] == NULL)
{
Trie *temp = new Trie;
temp->isword = false;
for(int j=0;j<26;j++)
temp->next[j] = NULL;
p->next[word[i]-'a'] = temp;
}
p = p->next[word[i]-'a'];
i++;
}
p->isword = true;
}
bool Find(Trie *root, char *word)
{
Trie *p = root;
int i = 0;
stack<int> s;while(!s.empty()) s.pop();
while(word[i] != '\0')
{
if(p->next[word[i]-'a'] == NULL)
return 0;
p = p->next[word[i]-'a'];
if(p->isword && word[i]) s.push(i+1);
i++;
}
while(!s.empty())
{
bool ok = true;
i = s.top(); s.pop();
p = root;
while(word[i])
{
if(p->next[word[i]-'a'] == NULL)
{
ok = false;
break;
}
p = p->next[word[i]-'a'];
i++;
}
if(ok && p->isword)
return 1;
}
return 0;
}
char s[MAXN][27];
int main()
{
int n = 0;
Trie *root = new Trie;
root->isword = false;
for(int j=0;j<26;j++)
root->next[j] = NULL;
while(scanf("%s", s[n]) != EOF)
{
insert(root, s[n]);
n++;
}
for(int i=0;i<n;i++)
{
if(Find(root, s[i]))
printf("%s\n", s[i]);
}
return 0;
}