http://acm.hdu.edu.cn/showproblem.php?pid=1247
字典树的题目,以前自己没想到怎么做就一直都放在那里了。
今天突然看到,然后想了下,自己有了思路然后就写了下。虽然WA了几次,但总算是让我过了。。。~~o(>_<)o ~~
View Code
1 #include <iostream> 2 #include <algorithm> 3 #include <string> 4 using namespace std; 5 const int maxn = 50005; 6 string str[maxn],s[maxn]; 7 int num; 8 9 typedef struct node 10 { 11 int f; 12 node *next[26]; 13 }*link; 14 link head; 15 16 int dtree(string str,int k,int n,int r) 17 { 18 int i,j,f,flag; 19 i=k; 20 f=0; 21 flag=1; 22 link p,now; 23 p=head; 24 for(;i<n;i++) 25 { 26 if(!p->next[str[i]-'a'] && r) 27 { 28 now=(link)malloc(sizeof(node)); 29 now->f=0; 30 for(j=0;j<26;j++) 31 now->next[j]=NULL; 32 now->f=0; 33 p->next[str[i]-'a']=now; 34 p=now; 35 } 36 else if(!p->next[str[i]-'a'] && !r) 37 { 38 return 0; 39 } 40 else 41 { 42 p=p->next[str[i]-'a']; 43 if(p->f && r && !f) 44 { 45 f=dtree(str,i+1,n,!r); 46 } 47 } 48 } 49 if(!p->f && r) 50 { 51 p->f=1; 52 } 53 if(p->f && !r) 54 { 55 return 1; 56 } 57 else return f; 58 } 59 60 bool cmp_1(string s1, string s2) 61 { 62 return s1.length()<s2.length(); 63 } 64 65 bool cmp_2(string s1,string s2) 66 { 67 return s1<s2; 68 } 69 70 void init() 71 { 72 int i; 73 head=(link)malloc(sizeof(node)); 74 head->f=0; 75 for(i=0;i<26;i++) 76 head->next[i]=NULL; 77 } 78 79 int main() 80 { 81 int i,n,f,len; 82 i=0; 83 init(); 84 while(cin>>str[i]) 85 { 86 i++; 87 //if(str[i-1]=="sssss") 88 // break; 89 } 90 n=i; 91 sort(str,str+n,cmp_1); 92 num=0; 93 for(i=0;i<n;i++) 94 { 95 len=str[i].length(); 96 f=dtree(str[i],0,len,1); 97 if(f) 98 { 99 s[num++]=str[i]; 100 } 101 } 102 sort(s,s+num,cmp_2); 103 for(i=0;i<num;i++) 104 cout<<s[i]<<endl; 105 return 0; 106 }
1.先把单词按照长度排序,然后依次放入字典树。
2.在单词放入字典树的过程中,如果这个单词的第K个字母是某个单词的结尾,则将第[K...N-1]个字母当做一个单词string,放入字典树中查询。
3.如果要查询到string结尾,并且恰好是某个单词的结尾,则说明这也是一个单词,说明恰好是两个单词的组成;
如果查询到string结尾,但是却并不是某个单词的结尾,则说明string只是某个单词的子串,并不是某个单词,所以返回string不存在。
4.如果在查询的过程中要创建新的节点,则说明string是一个新的单词,所以不用创建之间就返回string不存在。