单词查找树,利用字符串的公共前缀来减少查询时间
复杂度为O(n)
利用数组来建树
const int N; //树的最大节点数
const int M=26; //数的子节点的数目 举例26为小写字母作为可能的子节点
vector<vector<int>> trie(N,vecotr<int>(M,0)); //trie树数组 存的是索引
vector<int> cnt[N]; //储存终点节点的个数
int idx=0; //0是根节点且为空
void trie_insert(string s)
{
int p=0; //索引指针 从根节点开始
for(int i=0;i<(int)s.length();i++)
{
int word=s[i]-'a'; //假设是只含有小写字母的例子
if(!trie[p][word])trie[p][word]=++idx; //如果当前没有这个节点就新创建一个
p=trie[p][word]; //进入到这个节点
}
cnt[p]++; //以这个节点结束的标记一下
}
int trie_query_times(string s) //查询字符串出现的次数
{
int p=0; //根节点
for(int i=0;i<(int)s.length();i++)
{
int word=s[i]-'a'; //假设是只含有小写字母的例子
if(!trie[p][word])return 0; //如果没有这个节点的话就直接返回
p=trie[p][word]; //进入到这个节点
}
return cnt[p]; //走到了最后
}
int trie_query_prefix(string s) //查询该字符串的前缀的数量
{
int p=0; //根节点
int ans=0; //答案
for(int i=0;i<(int)s.length();i++)
{
int word=s[i]-'a';
if(!trie[p][word])break; //计数已经完成
p=trie[p][word];
ans+=cnt[p]; //加上这个前缀的数量
}
return ans;
}