AcWing 835. Trie字符串统计解析
原题链接
简单
作者:
shannai37
,
2023-09-19 18:44:35
,
所有人可见
,
阅读 72
#include<iostream>
using namespace std;
const int N = 100010;
int son[N][26]; // son[][]存储子节点的位置,一个节点最多有26个分支
int cnt[N]; // cnt[]存储以某节点为结尾的字符串个数(相当于给某节点做标记)
int idx; // idx表示节点的编号,idx=0是0号节点,即根节点
char str[N]; // str[]存储输入的字符串
void insert(char *str)
{
int p = 0; // p的作用类似指针,p的值表示p当前指向哪个节点
for(int i = 0;str[i];i ++)
{
int u = str[i]-'a'; // 将字母a~z转换成数字0~25存储进数组中
// p表示的是现在指向的是哪个节点,u表示的是哪个字母,son[p][u]不为空就证明有以这个字母为值的子节点
// 如son[0][2] = 1 -> 意思就是我从根节点沿着c这条边走到了节点1
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; // 若该节点不存在,即该字符串不存在,即没有查询到
p = son[p][u]; // 令p指向子结点
}
return cnt[p]; // 返回字符串出现次数
}
int main()
{
int n;
scanf("%d",&n);
while(n--)
{
string op; //定义char op[2];scanf("%s",op); op[0] =='I' 这样会更快
cin>> op;
scanf("%s",str);
if(op=="I")insert(str);
else printf("%d\n",query(str));
}
return 0;
}