题目地址: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 */