题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247
题解:给一些单词,找出那些可以分成另外的两个单词的单词,字典树
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXN 50002
typedef struct node
{
struct node *child[26];//存储下一个字符
int cnt;//该节点是否是单词的结尾
}node,*Trie;
Trie root;//字典树的根节点
char words[MAXN][16];
void insert(char *str)
{
int i,j,index,len;
Trie current,newnode;
len=strlen(str);
if(len==0)
return;//单词长度为0
current=root;//当前节点为根节点
for(i=0;i<len;++i)
{
index=str[i]-'a';
if(current->child[index]!=NULL)//字典树存在该字符
{
current=current->child[index];
}
else
{
newnode=(struct node *)malloc(sizeof(struct node));//新增一节点
for(j=0;j<26;++j)
newnode->child[j]=NULL;
newnode->cnt=0;
current->child[index]=newnode;
current=newnode;//修改当前节点
}
}
current->cnt=1;//该节点是单词的尾
}
int query(char *str)
{
int i=0,index,len,ans;
int top=0,stack[1000];
Trie current;
len=strlen(str);
if(len==0)
return 0;
current=root;//从根节点开始查找
while(str[i])
{
index=str[i++]-'a';
if(current->child[index]==NULL)
return 0;//字典树不存在此单词
current=current->child[index];
if(current->cnt&&str[i])//找到该单词含有子单词的分隔点
stack[top++]=i;
}
while(top)
{
ans=1;
i=stack[--top];
current=root;
while(str[i])
{
index=str[i++]-'a';
if(current->child[index]==NULL)
{
ans=0;
break;
}
current=current->child[index];
}
if(ans&¤t->cnt)
return 1;
}
return 0;
}
void Del(Trie root)//释放内存
{
int i;
if(root==NULL)
return;
for(i=0;i<26;++i)
{
if(root->child[i]!=NULL)
Del(root->child[i]);
}
free(root);
root=NULL;
}
int main()
{
int i,cnt=0;
root=(struct node *)malloc(sizeof(struct node));
for(i=0;i<26;++i)
root->child[i]=NULL;
root->cnt=0;
while(scanf("%s",words[cnt])!=EOF)
{
insert(words[cnt]);
cnt++;
}
for(i=0;i<cnt;++i)
{
if(query(words[i]))
printf("%s\n",words[i]);
}
Del(root);
return 0;
}