上进小青年

导航

字典树

字典树(又叫单词查找树、Trie树,TrieTree),能很好地处理和“串”相关的检索问题。字典树很好地利用了串的公共前缀,节约了存储空间。 字典树的插入(Insert)、删除(Delete)和查找(Find)都非常简单,用一个一重循环即可,即第i次循环找到前i个字母所对应的子树,然后进行相应的操作。

字典树能很好地利用串的公共前缀,节约了存储空间。 同时用它来检索同样有着比较高的效率。

建树步骤:对于输入的字符串,依次把他们放入树中,如果字母已经在树中,把此结点作为根节点,并且继续向下面查找,                直到把该字符串里的字母全部放进去,并把最后的结点做上标记,如果下一个字母不在树中,那就新建一个结点,              并把此结点作为根节点继续查找。

查找步骤:对于要查找的字符串,依次逐个查找字母,如果存在当前字母就继续查找,如果树种不存在当前字母,直接退出               函数。如果一直查找并且当前字母都在树中,最后一个字母在树中也是有标记的,那么这个字符串就是在的。

上面这张图就是a,as,asp,asc,an,ascii,bas,basic的对应的字典树。

模板

输入n,后面n行输入字符串,而后输入单词,判断该的那次是否在前面的n个单词中出现过

 1 #include<stdio.h>
 2 #include<iostream>
 3 #include<string.h>
 4 const int maxn=10000;///这个maxn不是随便写的,他的大小是提前估计出可能有多少的结点数目
 5 int tot;             ///结点编号,模拟申请新节点,静态申请
 6 int trie[maxn][26];  ///26是因为我们假设每个节点的分支是26个字母,其他适情况而定
 7 bool isw[maxn];      ///若该节点是单词结尾,则为true,否则为false
 8 
 9 void insert(char *s,int rt){///此rt非彼rt,这个rt只是函数的一个参数,当函数调用完毕后rt也就会被释放,所以
10                             ///下面的rt始终都是从1,即每次都是从根节点开始执行的
11  
12  for(int i=0;i<strlen(s);i++){
13     int x=s[i]-'a';          ///假设单词都是有小写字母组成的
14      if(trie[rt][x]==0){     ///若没有该结点,申请新结点
15         trie[rt][x]=tot++;
16     }
17     rt=trie[rt][x];
18  }
19  isw[rt]=true;
20 }
21 bool find(char *s,int rt){
22 for(int i=0;i<strlen(s);i++){
23     int x=s[i]-'a';
24     if(trie[rt][x]==0){
25         return false;
26     }
27     rt=trie[rt][x];
28 }
29 return isw[rt];
30 }
31 char s[22];
32 int main()
33 {
34     int n;
35     while(scanf("%d",&n)){char s[105];
36             int tot=1;
37     int rt=tot++;///rt始终不变
38     memset(trie[rt],0,sizeof(trie[rt]));
39     memset(isw,false,sizeof(isw));
40         for(int i=0;i<n;i++){
41             scanf("%s",s);
42             insert(s,rt);///每次都是从根节点开始执行的
43         }
44         while(scanf("%s",s),s[0]!='#'){
45             if(find(s,rt)){
46                 printf("%s 在字典中\n",s);}
47                 else printf("%s 不在字典中\n",s);
48 
49         } 
50     }
51 }
View Code

 

posted on 2016-08-13 16:39  上进小青年  阅读(194)  评论(0编辑  收藏  举报