字符串匹配--字典树模板

字典树就是将一个个单词按照字母顺序建成树,可以用于单词去重、计算每种单词的出现次数、计算共出现多少种单词

本来用结构体存储的,但是后来做题的时候发现结构体内能开的节点大小确实有限,所以就去掉了结构体。

 1 //关于引用说明:如果引用创建后,注意是否会修改x引用的对象,即x引用某值,再修改x的值。
 2 
 3 #include<stdio.h>
 4 #include<string.h>
 5 const int maxm=5050;    //maxm是所有单词的总长度
 6 
 7 int Nxt[maxm][26];    //字母结点
 8 int tail[maxm];        //记录某个结点是否为单词结尾,可以用bool型仅记录是否结尾,也可以int型记录其作为结尾的单词编号或记录单词出现过多少次
 9 int Cnt[maxm];            //每个节点及后继所代表的单词数有多少,适用于字典树需要删除节点的时候使用
10 int size;
11 
12 void init_trie(){        //初始化函数
13     memset(Nxt[0],0,sizeof(Nxt[0]));
14     memset(tail,0,sizeof(tail));
15     memset(Cnt,0,sizeof(Cnt));
16     size=1;
17 }
18 
19 void insertword(char s[]){    //添加单词函数
20     int p=0;
21     for(int i=0;s[i];++i){
22         int &x=Nxt[p][s[i]-'a'];
23         if(!x){
24             memset(Nxt[size],0,sizeof(Nxt[size]));
25             x=size++;
26         }
27         Cnt[x]++;                //用于记录后继单词数
28         p=x;
29     }
30     tail[p]++;    //可以通过函数额外传一个单词编号的int型参数,此处即可将tail[p]赋为单词编号记录下来;也可以根据此处tail[p]的初始值是否为0,若为0可以用计数器加值记录共出现多少不同的单词;换成tail[p]++语句也可以用于记录某个单词出现过多少次
31 }
32 
33 void deleteword(char s[]){
34     int p=0;
35     for(int i=0;s[i];++i){
36         int x=Nxt[p][s[i]-'a'];
37         Cnt[x]--;
38         p=x;
39     }
40     tail[p]--;
41 }
42 
43 bool findword(char s[]){    //查询单词函数,也可以返回int型查询该单词出现过多少次
44     int p=0;
45     for(int i=0;s[i];++i){
46         int &x=Nxt[p][s[i]-'a'];
47         if(!x)return 0;
48         p=x;
49     }
50     return tail[p];
51 }
52 
53 int main(){
54     char word[50];
55     int i;
56     init_trie();
57 //    for(i=1;i<=10;i++){scanf("%s",word);insertword(word);}
58 //    printf("
");
59 //    for(i=1;i<=20;i++){scanf("%s",word);printf("%d
",findword(word));}
60     while(1){
61         int t;
62         scanf("%d%s",&t,word);
63         if(t==1)insertword(word);
64         if(t==2)deleteword(word);
65         if(t==3)printf("%d
",findword(word));
66     }
67     return 0;
68 }

 

原文地址:https://www.cnblogs.com/cenariusxz/p/4509067.html