21.Trie字符串统计(c++)

维护一个字符串集合,支持两种操作:

  1. I x 向集合中插入一个字符串 x;
  2. Q x 询问一个字符串在集合中出现了多少次。

共有 NN 个操作,输入的字符串总长度不超过 105,字符串仅包含小写英文字母。

输入格式

第一行包含整数 N,表示操作数。

接下来 N 行,每行包含一个操作指令,指令为 I xQ x 中的一种。

输出格式

对于每个询问指令 Q x,都要输出一个整数作为结果,表示 xx 在集合中出现的次数。

每个结果占一行。

数据范围

1≤N≤2∗104

输入样例:

5
I abc
Q abc
Q ab
I ab
Q ab

输出样例:

1
0
1

代码如下:

#include<iostream>
using namespace std;
const int N=100010;
int son[N][26];//son[N][26] 记录的是当前 每一个父节点 所有子树26个之母当中的一个;
              //比如 son[1][0]=2 表示 1 结点的一个值为a的子结点为结点2; 
int cnt[N];//存储以当前这个节点结尾的单词有多少个
int idx;//当前用到了哪1个下标,下标是0的节点既是根节点,又是空节点
char str[N];
void insert(char str[])//插入的操作 
{
	int p=0;//从根节点开始
	for(int i=0;str[i];i++)//如果检测null或者0(意思就是空)简单说就是依次读完这个字符串,然后退出循环
	{
		int u=str[i]-'a';//转换成相应数值 
		if(!son[p][u]) son[p][u]=++idx;//如果当前没有这个节点,就在第p个父节点下方第u个子节点上新增一个点,记为 idx+1.
		p=son[p][u];//将p指向它的子节点,然后继续进行增加 其所在节点下一个字符的操作
	}
	cnt[p]++;//结束的时候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 不存在 u 这个儿子,说明当前集合不存在这个单词,直接返回 0 即可
		p= son[p][u];//否则的话就走到下一个点
	}
	//结束的时候p指向的点对应字符串的最后一个字符。 
	return cnt[p];//返回以 p 结尾的字符串的数量
}
int main()
{
	int n;
	cin>>n;
	while(n--)
	{
		char op[2];
		scanf("%s%s",op,str);//读入字符串。 
		if(op[0]=='I') insert(str);//调用函数 
		else printf("%d\n",query(str));
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瘦出腹肌的JingLi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值