trie算法

news2024/11/24 19:59:54

1、定义

高效的存储和查找字符串集合的数据结构

它的优点是:利用字符串的公共前缀来减少查询时间,最大限度地减少无谓的字符串比较,查询效率比哈希树高

2、构建

我们可以使用数组来模拟实现Trie树。

我们设计一个二维数组 son[N] [26] 来模拟整个树的结构,而cnt[N] 来记录单词个数。

举个例子: son[1][1]=2 代表的是 1号节点 的一个值为b的节点 是 2号节点。而son[1][0]=0 则表示1号节点不存在 值为 a 的节点。

在这里插入图片描述

在这里插入图片描述

3、代码分析

1、定义

son[N][26]

下标是x的点

x这个节点的所有的儿子是去存储到son[x][26]里面

son[x][0]就是第一个节点 son[x][1]就是第二个节点

cont[x]表示以x为结尾的单词有多少个

int son[N][26], cnt[N], idx;
// 0号点既是根节点,又是空节点
// son[][]存储树中每个节点的子节点
// cnt[]存储以每个节点结尾的单词数量
2、插入操作
// 插入一个字符串
void insert(char *str)
{
    int p = 0;
    //从根节点开始,从前往后遍历
    for (int i = 0; str[i]; i ++ )
    {
        //将a-z 映射成  0 - 25
        int u = str[i] - 'a';
        //如果当前节点不存在 => p节点不存在u这个儿子
        //就创建出来
        if (!son[p][u]) son[p][u] = ++ idx;
        //将该值赋给p
        p = son[p][u];
    }
    //以该点为结尾的数字多了一个
    cnt[p] ++ ;
}
3、查询操作
// 查询字符串出现的次数
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];
}

3.题目

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

1、 I x向集合中插入一个字符串 x;
2、 Q x询问一个字符串在集合中出现了多少次。
共有 N个操作,所有输入的字符串总长度不超过10^5 ,字符串仅包含小写英文字母。

输入格式

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

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

输出格式

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

每个结果占一行。

数据范围

1≤N≤2∗10^4

输入样例:

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],idx,cnt[N];
char str[N];

//向集合中插入一个字符串 x
void insert(char str[])
{
	int p = 0;
	for (int i = 0; str[i]; i++)
	{
	int u = str[i] - 'a';
	//将这个字符从a-z变成 0-25
	if (!son[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;
	cin >> n;
	while (n--)
	{
		char op[2];
		cin >> op >> str;
		if (op[0] == 'I') insert(str);
		else cout << query(str)<< endl;
	}
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1992807.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WhatsApp收不到验证短信的原因及解决方案

在使用WhatsApp进行账号注册或验证过程中&#xff0c;有时会遇到无法收到验证短信的情况。这种情况可能会给用户带来诸多不便&#xff0c;但通常可以通过一些简单的方法来解决。本文将详细分析收不到验证短信的可能原因&#xff0c;并提供相应的解决方案&#xff0c;帮助用户顺…

LeetCode_sql_day15(262.行程与用户)

描述&#xff1a;262. 行程和用户 - 力扣&#xff08;LeetCode&#xff09; 取消率 的计算方式如下&#xff1a;(被司机或乘客取消的非禁止用户生成的订单数量) / (非禁止用户生成的订单总数)。 编写解决方案找出 "2013-10-01" 至 "2013-10-03" 期间非禁止…

EMF矢量图工具Graphpad Prism(棱镜科研绘图工具)

Graphpad Prism 是一款功能强大、专业实用的棱镜科研绘图软件&#xff0c;专为科研工作者而设计研发&#xff0c;可帮助用户进行专业便捷的科研图像绘制&#xff0c;通过该款软件用户可以进行新型子列图进行创建&#xff0c;可以进行平滑的线性图进行绘制&#xff0c;可以说是一…

【汉明距离总和】python刷题记录

R4-数与位篇 class Solution:def totalHammingDistance(self, nums: List[int]) -> int:#创建计数器trieCounter()max_bitlen(bin(max(nums)))-2ret0for i,num in enumerate(nums):for j in range(max_bit):#一位位地取出来bit(num>>j)&1if bit:reti-trie[j]trie[…

同态加密和SEAL库的介绍(一)简介

写在前面&#xff1a; 最近在做同态相关的内容&#xff0c;这里记录下相关的知识点和所踩过的坑&#xff0c;希望对大家有帮助。预计分几篇来详细介绍&#xff0c;从概念简介到不同模式介绍&#xff0c;具体包括了每种模式的编解码和加解密以及他们性能的比对。 虽然同…

MySQL 8.0新特性

文章目录 一. 账户与安全1. 查看用户信息2. 用户权限管理范围3. 用户创建和授权1&#xff09; 创建并授权用户2&#xff09;登录zhp&#xff0c;密码zhp.1221。验证数据库权限3&#xff09;查看用户权限4&#xff09;撤销用户权限5&#xff09;用户重命名&修改密码6&#x…

端到端 AWS 定量分析:使用 AWS 和 AWSCLI 自动运行脚本

使用 AWSCLI 启动、运行和关闭 AWS 服务器 添加图片注释&#xff0c;不超过 140 字&#xff08;可选&#xff09; 欢迎来到雲闪世界。我们开发了两个 Python 脚本&#xff1b;一个用于为我们获取数据&#xff0c;另一个用于使用 sklearn 的决策树分类器处理数据。然后&#xf…

NAT、服务代理、内网穿透

文章目录 NAT技术NAT IP转换过程NATPNAT的优点NAT的缺点 代理服务器正向代理反向代理 内网穿透和内网打洞内网穿透内网穿透 NAT技术 NAT技术即网络地址转换技术。用于将私有IP地址转换为公共IP地址&#xff0c;以便在互联网或其他外部网络中通信。为了解决IPv4协议下IP地址不足…

【Nacos无压力源码领读】(三) Nacos 配置中心与热更新原理详解超详细解读

本文将从 Nacos 配置中心的基本使用入手, 详细介绍 Nacos 客户端发布配置, 拉取配置, 订阅配置的过程以及服务器对应的处理过程; 配置订阅以及热更新原理相关的部分, 我看了主流的博客网站, 绝对没有比这更详细的讲解; 如果在阅读过程中对文中提到的 SpringBoot 启动过程以及…

交叉编译nginx1.20.0

一、说明 简略写一下过程&#xff0c;仅用于参考&#xff0c;建议与其他交叉编译教程一起看&#xff0c;检查是否有遗漏的问题。 二、源码修改 1、auto/cc/name vi auto/cc/name 注释 21 行 exit 1。 2、auto/types/sizeof vi auto/types/sizeof 将 15 行处的” ngx_size”…

数字图像处理(理论篇)专栏介绍

专栏导读 数字图像处理是计算机视觉领域的基石&#xff0c;它涉及到图像的获取、表示、处理和分析等多个方面。本专栏将通过一系列精心挑选的实战案例&#xff0c;引导读者从基础概念到高级技术&#xff0c;逐步深入学习数字图像处理的各个方面。 专栏目录 数字图像处理 第一…

离线+树状数组,ABC253 F - Operations on a Matrix

一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 F - Operations on a Matrix 二、解题报告 1、思路分析 我们通过差分树状数组&#xff0c;可以轻松解决操作1 操作3我们也可以通过树状数组来获取对应列的值 关键是操作2会对操作3造成影响 所以我们先对…

你了解堆和栈的由来吗?

人们提出内存中堆和栈这两个概念&#xff0c;肯定是要解决当时所遇到的问题&#xff0c;不会为了提出概念而提概念。堆和栈都是为了解决一些问题而发展出来的结果&#xff0c;并没有任何的高深之处。 要搞懂堆和栈的概念是如何来的&#xff0c;就需要从计算机诞生时说起了。 …

UE中的运行时Mesh - 学习笔记

UE中的运行时Mesh Runtime Mesh 广泛应用于仿真、游戏及医疗等相关应用领域。 运行时Mesh可以摆脱UE编辑器的依赖&#xff0c;独立开发相对独立的应用程序。 应用示例 地质领域&#xff1a; 模型编辑修改&#xff1a;膨胀 导入、材质设置、补洞及简化&#xff1a; mar…

【Java】韩顺平Java学习笔记 第23章 反射

文章目录 需求和快速入门反射原理反射相关主要类反射的优点和缺点及其优化Class类Class类常用方法获取Class类对象的六种方式有Class对象的类型 类加载动态加载和静态加载类加载时机类加载流程图类加载五个阶段加载阶段连接阶段-验证连接阶段-准备连接阶段-解析总结Initializat…

【Bug记录】operator->返回类型错误导致operator->调用不了

项目场景&#xff1a; 模拟list&#xff0c;出现operator->调用不了的情况&#xff0c;这是什么情况呢&#xff1f;&#xff1f;&#xff1f; 问题描述 这里我是明确写了operator->函数的&#xff1a; 但是却有下面报错&#xff1a; 原因分析&#xff1a; 这里有…

python判断和循环语句

python判断语句 1、单个条件判断 if 条件:满足条件要做的事情1满足条件要做的事情2 else:不满足条件要做的事情3不满足条件要做的事情2 2、多个条件判断&#xff08;满足条件1就不会判断条件2&#xff09; else可以省略不写 if 条件1:满足条件1要做的事情a满足条件1要做的事…

JavaEE从入门到起飞 (三) ~AOP

晚上好&#xff0c;愿这深深的夜色给你带来安宁&#xff0c;让温馨的夜晚抚平你一天的疲惫&#xff0c;美好的梦想在这个寂静的夜晚悄悄成长。 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 了解面向切面编程&#xff08;AOP&#xf…

牛客网每日刷题之 HJ99.自守数(C++)

在不断学习的过程中也不能忘记了基础知识的巩固&#xff0c;在学习新的知识后要学会去举一反三&#xff0c;前不久我刚刚了解了一些关于 string 类的知识&#xff0c;对牛客网的 自守数 有了新的解题思路&#xff0c;让我们一起看看这道题吧 思路解析 a. 整数方法 1. 首先我们知…

C++(2):λ表达式,类函数重载

λ表达式 [&]捕获前面所有 [i] j闭包函数内访问不了&#xff0c;在函数内i只能用不能改 [&I,j] i在函数内可改j不行 未捕获可以充当函数指针使用 new,delete和malloc,free区别 new会调构造函数 malloc不会&#xff0c;delete会调析构函数free不会malloc调用需要强转…