标签:
字典树(又叫单词查找树、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 }
标签:
原文地址:http://www.cnblogs.com/shangjindexiaoqingnian/p/5768294.html