字典树,又称 Trie 树,是一种树形结构。典型应用是用于统计,排序和保存大量的字符串(但不仅限于字符串)。主要思想是利用字符串的公共前缀来节约存储空间。
上图便是一棵字典树,“从根节点到任意一个红色节点的路径上的字母组成一个单词”。 字典树主要包含两种操作,插入和查找。也有一说亦含有删除操作,但这基本属于查找操作的变种,初步学习需要重点掌握插入和查找操作。
字典树可以高效的用来统计某个字符串出现的次数,字典树可以说是必须要掌握的,不然无法学习Aho-Corasick自动机。
#include<cstdio>
#include<cstdlib>
using namespace std;
char s[11]; //此代码中字典树中的单词长度不超过 10
struct Trie{
Trie* next[26]; //结构体指针
int sum; //从根结点到当前结点之间单词出现的次数
Trie(){ //构造函数 便于初始化
for(int i=0;i<26;i++){ //初始化
next[i]=NULL;
}
sum=0;
}
}root;
void insert(char* s) //创建字典树 在字典树上插入结点
{
Trie* p=&root;
for(int i=0;s[i];i++){
if(p->next[s[i]-'a']==NULL){
p->next[s[i]-'a']=new Trie;
}
p=p->next[s[i]-'a'];
p->sum++;
}
}
int find(char* s) //查找单词
{
Trie* p=&root;
for(int i=0;s[i];i++){
if(p->next[s[i]-'a']==NULL)return 0;
else p=p->next[s[i]-'a'];
}
return p->sum;
}
int main(){
while(gets(s)&&s[0]!='\0') //读取字典中的单词 将其插入字典树中
insert(s);
while(scanf("%s",s)==1){ //在字典树中查找单词出现的次数
printf("%d\n",find(s));
}
return 0;
}