Trie树模板1字符串统计

Trie树模板1字符串统计

我们首先来了解一下字典树,首先看一下一张字典树的图片

字典树就是一个可以高效存储查找字符串的树,比如上面这个字典树就是存储abc,acb,bac的字典树。

1.插入操作(insert)

首先假设我们要再插入acd这个字符串,该怎么办呢?

很简单我们先从根节点遍历下来,当没找到某一个字符的时候,就增添一条路径,这时侯还得在最后的结点上面做一些标记,因为假设我们还有ab这个字符串,我们待会查找的时候他就不会知道这里还有一个字符串。

这就是完成查找操作的字典树。

2.查找操作(query)

我们从跟结点向下遍历,如果没有看到某一个字符,就说明没有这个字符,一支搜索到目标字符串的最后一个字符哪里才算查找成功。

完整代码:

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 101000;

int son[N][26];//每一个结点最多向外展开26条边
int cnt[N];//表示以当前字符结尾的单词有几个
int idx;//当前用到了哪个下标,下标是0的节点,是根结点,也是空结点
char str[N];
void insert(char str[])
{
    int p = 0;
    for(int i = 0; str[i]; i ++ )
    {
        int u = str[i] - 'a';//对应子结点编号
        if(!son[p][u])//p这个结点不存在u这个结点
            son[p][u] = ++idx;//创建出来
        p = son[p][u];//走下去
    }
    cnt[p] ++ ;
}

int query(char str[])//跟插入操作类似
{
    int p = 0;
    for (int i = 0; str[i]; i ++ )
    {
        int u = str[i] - 'a';
        if(!son[p][u]) return 0;
        p = son[p][u];
    }
    return cnt[p];
}

int main()
{
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i ++ )
    {
        char op[2];
        scanf("%s%s", op, str);
        if(op[0] == 'I') insert(str);
        else printf("%d\n",query(str));
    }
    return 0;
}
posted @ 2022-07-21 13:45  ljfyyds  阅读(45)  评论(0)    收藏  举报