字典树Trie(模板)
字典树也称前缀树,用来保存字符串集合,有插入和查询操作,插入操作是将一个字符串加入到字典树中,查询操作一半是查询某个前缀、某个单词以及它们出现的次数等等,树结构通常用一个二维数组来存储,trie[i][j]==k表示结点编号为i的第j个孩子的编号为k,下面的这篇博客专门对字典树做了详解,讲的很详细
char s[15];
int trie[maxn][26],tot;//maxn是Trie树的结点总数,根据题目而定
int cnt[maxn];//记录每个结点对应的前缀出现的次数
void insert(){//插入
int node=0;
for(int i=0;s[i];++i){
int id=s[i]-'a';
if(trie[node][id]==0) trie[node][id]=++tot;
node=trie[node][id];
++cnt[node];//前缀后移一个位置保存
}
}
int query(){//查询
int node=0;
for(int i=0;s[i];++i){
int id=s[i]-'a';
if(trie[node][id]==0) return 0;
node=trie[node][id];//node经过此循环后变成前缀最后一个字母所在位置的后一个位置
}//因为前缀后移了一个保存,所以此时的cnt[node]就是要求的前缀出现的次数
return cnt[node];
}
此外还有一种借助指针的链表写法
char s[15];
struct node{
int cnt;//前缀数量
node* next[26];
}*trie;
node* build(){
node *p=new node();
p->cnt=0;
memset(p->next,0,sizeof(p->next));
return p;
}
void insert(){
node *p=trie;
for(int i=0;s[i];++i){
int id=s[i]-'a';
if(!p->next[id]) p->next[id]=build();
p=p->next[id];
++p->cnt;
}
}
int query(){
node* p=trie;
for(int i=0;s[i];++i){
int id=s[i]-'a';
if(!p->next[id]) return 0;
p=p->next[id];
}
return p->cnt;
}