题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1247
本题为简单字典树问题。
解题思路:进行插入的时候,使用flg标记每个单词的结尾,当flg为true时表示到了某一个单词的结尾
当为false时即不是某一个单词的结尾。进行查找的时候当一个单词的前一部分是某个单词的时候
则判断后面一部分是否也是一个已经存在的单词,是则返回true否则返回false。
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char list[50001][26];
struct node
{
bool flg;
node *next[26];
}*root;
void insert(char str[])
{//向字典树种插入单词
int i,len = strlen(str);
node *newset,*current = root;
for(i = 0; i < len ; i++)
{
int k = str[i] - 'a';
if(current->next[k] != NULL)
current = current->next[k];
else
{//新建一个结点,并将当前位置标记为不是单词结尾
newset = (node*)malloc(sizeof(node));
memset(newset->next,NULL,sizeof(newset->next));
current->next[k] = newset;
current = newset;
current->flg = false;
}
}
//标记单词结尾。
current->flg = true;
}
bool find(char str[])
{
int k,i,len = strlen(str);
//当单词长度为0的时候返回false
if(len == 0)
return false;
node *current = root;
for(i = 0; i < len; i++)
{
k = str[i] - 'a';
//当单词不存在的时候返回false
if(current->next[k] == NULL)
return false;
else
current= current->next[k];
}
//返回str结尾的标记,
return current->flg;
}
bool check(char str[])
{
int i,len = strlen(str);
//当单词长度为0的时候返回false
if(len == 0)
return false;
node *current = root;
for(i = 0; i < len ; i++)
{
int k = str[i] - 'a';
//当为NULL的时候false
if(current->next[k] == NULL)
return false;
else
if(current->next[k]->flg)//当str的前一部分为已经存在的单词时
{
if(find(str+i+1))//查看后面部分是否为一个已经存在的单词
return true;
}
current = current->next[k];
}
//当没找到的时候返回false。
return false;
}
int main()
{
int num = 0;
root = (node*)malloc(sizeof(node));
memset(root->next,NULL,sizeof(root->next));
while(~scanf("%s",list[num]))
insert(list[num++]);
for(int i = 0; i < num ; i++)
{
if(check(list[i]))
printf("%s\n",list[i]);
}
return 0;
}
/*
adsf
dsf
ads
a
d
gad
af
f
dfe
def
afew
dsfads
afds
输出:
adsf
dsfads
*/