字典树

字典树可以用来快速查找字符串前缀,当然,适当的变下形就可以解决需要很多了。

从根节点开始,每遇见一个红点就可以组成一个单词。

节点的建立:

  

 1 struct Nod{
 2     bool is;
 3     Nod *next[26];
 4     Nod(){
 5         is = false;
 6         for(int i = 0; i < 26; i ++){
 7             next[i] = NULL;
 8         }
 9     }
10 };

插入:

1 void mkTrie(Nod *root,char *s){
2     Nod*p = root;
3     for(int i = 0; s[i]; i ++){
4         int a = s[i] - '0';
5         if(p->next[a]==NULL)p->next[a] = new Nod;
6         p = p->next[a];
7     }
8     p->is = true;
9 }

删除:(很多题目有很多组数据,如果不删除释放空间的话,很容易导致Memory Limit Exceeded)

 1 void deleTrie(Nod *p){
 2     if(p == NULL) return;
 3     for(int i = 0; i < 26; i ++){
 4         if(p->next[i] != NULL){
 5             deleTrie(p->next[i]);
 6         }
 7     }
 8     free(p);
 9     return ;
10 }

 

查找:

1 int find(){
2     Nod* p = &t;
3     for(int i = 0; s[i]; i ++){
4         int a = s[i]-'a';
5         if(p->next[a]==NULL) return 0;
6         p = p->next[a];
7     }
8     return p->num;
9 }

HDU1671 为例。

大意是求是否有某个数为另外一个树的前缀。

假设X1X2X3...Xn为Y1Y2Y3...Yn的前缀,那么有两种情况。

(一):X在Y的后面,这时在插入X时,在Xn这里会有子节点。

(二):X在Y的前面,这时在插入Y时,在Xn这里会被标记。

AC代码为:

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 using namespace std;
 4 char str[20];
 5 bool flag;
 6 struct Nod{
 7     bool is;
 8     Nod *next[26];
 9     Nod(){
10         is = false;
11         for(int i = 0; i < 26; i ++){
12             next[i] = NULL;
13         }
14     }
15 };
16 void mkTrie(Nod *root,char *s){
17     Nod*p = root;
18     for(int i = 0; s[i]; i ++){
19         int a = s[i] - '0';
20         if(p->next[a]==NULL)p->next[a] = new Nod;
21         if(p->is){
22             flag = true;
23         }
24         p = p->next[a];
25     }
26     p->is = true;
27     for(int i = 0; i < 26; i ++){
28         if(p->next[i]!=NULL){
29             flag = true;
30             break;
31         }
32     }
33 }
34 void deleTrie(Nod *p){
35     if(p == NULL) return;
36     for(int i = 0; i < 26; i ++){
37         if(p->next[i] != NULL){
38             deleTrie(p->next[i]);
39         }
40     }
41     free(p);
42     return ;
43 }
44 int main(){
45     int T,n;
46     scanf("%d",&T);
47     while(T--){
48         scanf("%d",&n);
49         Nod *t = new Nod;
50         flag = false;
51         for(int i = 0; i < n; i ++){
52             scanf("%s",str);
53             if(!flag){
54                 mkTrie(t,str);
55             }
56         }
57         if(flag)cout << "NO\n";
58         else cout << "YES\n";
59         deleTrie(t);
60     }
61     return 0;
62 }

 

  

posted @ 2017-07-04 15:26  starry_sky  阅读(281)  评论(0编辑  收藏  举报