字典树统计单词
题意:给你n个单词,让你找出由其它2个单词构成的单词,并按字典序输出。注意输入时已经是按字典序输入的。
思路:在trie树中标记每个单词的结尾,查找时把单词分成两部分分别进行查找
详情见代码
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define maxn 511000
int cur=1;
char str[50005][30];
int vis[50005];
struct node
{
bool num;//记录单词的结尾
int next[30];
void init()
{
num=false;
memset(next,-1,sizeof(next));
}
} trie[maxn];
void insert(char *s,int len)
{
int p=0;
for(int i=0; i<len; i++)
{
int x=s[i]-'a';
if(trie[p].next[x]==-1)
{
trie[cur].init();
trie[p].next[x]=cur++;
}
p=trie[p].next[x];
//trie[p].num=false;
}
trie[p].num=true;//标记单词的结尾
}
bool find(char *s,int len)
{
int p=0;
//printf("%s\n",s);
for(int i=0; i<len; i++)
{
int x=s[i]-'a';
if(trie[p].next[x]==-1)return false;
p=trie[p].next[x];
}
if(trie[p].num)return true;//是单词结尾
return false;
}
int main()
{
int n=0;
trie[0].init();
while(scanf("%s",str[n])!=EOF)
{
int len=strlen(str[n]);
insert(str[n],len);
vis[n]=len;
n++;
}
for(int i=0; i<n; i++)
{
if(vis[i]>1)
{
for(int j=1; j<=vis[i]-1; j++)
{
if(find(str[i],j)&&find(str[i]+j,vis[i]-j))//判读是否是由两个单词组成
{
printf("%s\n",str[i]);
break;
}
}
}
}
return 0;
}