字典树


如上图

  1. 根节点什么都不存
  2. 其余结点存各自对应的一个字符
  3. 从根节点往下遍历,遍历的字符组成了存储的字符串

建树

next[i][c]表示字符串与之对应的(s[j]=c)下一个字符(s[j+1])存储的位置,idx用来给新的字符开辟新的空间

int next[MAX_N * 50][26], idx;

补:
inline int getnum(char ch) { return ch - 'a'; }

插入字符串

c=getnum(s[i])代表获取字符s[i]的ASCII码,next[p][c]代表下一个字符在next中的位置,这个for循环是用来迭代字符串s的,而p=next[p][c]是用来迭代字典树的。如果next[p][c]0(初始值是0),那么说明这个字符在字典树这个位置第一次出现给它开辟一个新的空间

inline void insert(const char* s) noexcept {
int p = 0, c;
for (int i = 0; s[i] != '\0'; ++i) {
c = get_num(s[i]);
if (!next[p][c]) next[p][c] = ++idx;
p = next[p][c];
}
exit[p] = true;
}

查找字符串

与插入原理相同,当next[p][c]为0说明在字典树中以s[0]>s[i1]为前缀的子串第一次出现s[i],说明没找到。

inline int find(const char* s) {
int p = 0;
for (int i = 0; s[i] != '\0'; ++i) {
int cn = get_num(s[i]);
if (!next[p][cn]) return 0;
p = next[p][cn];
}
//找到了,返回需要的东西
}

记录字符串第一次出现的索引

声明一个变量数组cnts[MAXN]每当第一次插入的时候使其值+1

记录字符串重复的次数

当遍历到s[i]==\0是如果idx没变让++cnts[p]

字典树数组开辟空间的大小


字典树的深度(高度)与所包含的字符串前缀的相似度有关,设每层的结点数目为x个,设字符串的长度最多m,共n个字符串。那么第一层就是一个,第二层为x2,第三层为x3·····依次类推那么,前缀相同且长度为k时,字典树所含有的结点的个数为i=0kxi+(mk)n。其中(mk)n为前缀不同剩余得结点数量的最大值,显然一般是比这个小的。以上公式前面是一个等比级数 ,得:

wk+11w1+(mk)n=(1k)n+nmmn

题目

1
2
3

posted @   管管19  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示