AcWing 835. Trie字符串统计

原题链接如下:
AcWing 835. Trie字符串统计

一、基本介绍
Trie树又称字典树、单词查找树。是一种能够高效存储和查找字符串集合的数据结构。咋看之下不是很复杂,但是仔细看代码又有点模糊。储存形式如下:
AcWing 835. Trie字符串统计_第1张图片
二、用数组来模拟Trie树的具体分析
在这里插入图片描述
插入操作的代码如下:

void insert(char *str)
{
    int p = 0;  //我们可以把p看成一个指向当前结点的指针
    for(int i = 0; str[i]; i++)
    {
        int u = str[i] - 'a'; //将字母映射成数字
        //该节点不存在,创建节点,其值为下一个节点位置
        if(!son[p][u]) son[p][u] = ++idx;//idx是记录当前是第几个创建的节点,同样也是该结点的唯一标识
        p = son[p][u];  //使“p指针”指向下一个节点位置
    }
    cnt[p]++;  //结束时的标记,也是记录以此节点结束的字符串个数
}

查询操作代码:

//基本上和插入操作一致
//因为无论是插入还是查询操作都需要遍历trie树
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;  //这里需要变动一下,该节点不存在,即该字符串不存在,返回出现次数0
        p = son[p][u]; 
    }
    return cnt[p];  //返回字符串出现的次数
}

题解完整代码:

#include
using namespace std;
const int N = 100010;

//son[][]存储子节点的位置,一个分支最多26条(因为一个全小写字母字串最长为26);
//cnt[]存储以某节点结尾的字符串个数(同时也起标记作用)
//idx和之前的单双链表的作用一样,用来记录这是到了第几个结点,每创建一个新节点+1
int son[N][26],cnt[N],idx;
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])son[p][u] = ++idx;
        p = son[p][u];//使“p指针”指向下一个节点位置
    }
    cnt[p]++;//记录字符串出现的次数+1
}

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;//如果查询到该节点不存在,也就是字符串不存在 返回出现次数0
        p = son[p][u];//使“p指针”指向下一个节点位置
    }
    return cnt[p];
}
int main()
{
    int m;
    cin>>m;//操作次数
    while(m--)
    {
        char op[2];
        scanf("%s%s",op,str);
        if(*op == 'I')insert(str);
        else printf("%d\n", query(str));
    }
    return 0;
}

你可能感兴趣的:(Acwing,c++,算法)