声明
本文资料参考acwing算法基础课
地址:https://www.acwing.com
概述
- 解决问题:保存字符串的hash
- 平均时间复杂度为O(size)
- 树的构成有26叉指针son[N][26],下一个可用结点idx,标记cnt[N]
- 这棵树的结点没有信息,信息直接保存在了路径上,这是为了随机访问
模板记忆
这个模板分为三个部分:
- 初始化:三个部分son[N][26],cnt[N],idx
- 插入:用p表示遍历到的结点:1字符定数字 2查改son 3改p 4改cnt
- 查询:1字符定数字 2查son 3改p 4改cnt
模板代码
int son[N][26], cnt[N], idx; // 树的表示,son是一棵树,其中的路径表示一个字母,故一个n位字符串要有n + 1个节点,cnt表示以这个节点结束的字符串数
void insert(char str[]) // 插入trie树
{
int p = 0; // 0是根节点,延伸以a-z开始的26棵树
// p在遍历的过程中是一个平台,从根节点到p的路径是已经遍历的字符串
for (int i = 0; i < strlen(str); i ++ ) // 遍历字符串
{
int u = str[i] - 'a'; // 字符转换成数字
if (!son[p][u]) son[p][u] = ++ idx; // 如果没有对应路径,创造路径,用++idx作为结尾
p = son[p][u]; // 更新p平台
}
cnt[p] ++ ; // 遍历结束p在整个字符串路径的结尾,cnt[p]标记一下
}
int query(char str[])
{
int p = 0; // 0是根节点,延伸以a-z开始的26棵树
// p在遍历的过程中是一个平台,从根节点到p的路径是已经遍历的字符串
for (int i = 0; i < strlen(str); i ++ ) // 遍历字符串
{
int u = str[i] - 'a'; // 字符转换成数字
if (!son[p][u]) return 0; // 如果没有对应路径,返回没查到
p = son[p][u]; // 否则更新平台
}
return cnt[p]; // 遍历结束返回cnt,没查到就是0
}