【C++算法模板】字典树,超详细注释带例题讲解

文章目录

    • 0)概述
    • 1)数据结构
    • 2)插入操作
    • 3)查询操作
    • 4)完整代码
      • 1. 字符数组
      • 2. 字符串

视频链接:F06 字典树(Trie)

0)概述

  • 是快速插入和查询字符串的多叉树结构,根节点编号为0,其余节点标识路径,还可以标记单词插入的次数,边表示字符。

在这里插入图片描述

1)数据结构

const int N=1e5+5;
char s[N]; // 每次输入的字符串,N是每个单词的最大长度
int ch[N][26]; // ch[p][j]:从节点p沿着j这条边走到的子节点,边为26个小写字母映射值为0~25
int cnt[N]; // cnt[p]:以节点p结尾的单词的插入次数
int idx; // 遍历因子

2)插入操作

  • insert函数,插入单个单词并建立字典树
// s:单词(字符串)
void insert(char *s) {
	int p=0; // 根节点编号为0
	// 枚举字符串每个字符
	for(int i=0;s[i];i++) {
		int j=s[i]-'a'; // a~z映射到0~25
		// 如果这个字符不是儿子节点,创建儿子,p指针再走到儿子
		if(!ch[p][j]) ch[p][j]=++idx; // 节点编号+1
		// 如果这个字符是儿子节点,p指针走到儿子节点
		p=ch[p][j];
	}
	cnt[p]++; // 以节点p结尾的单词插入的次数+1 
}

在这里插入图片描述

3)查询操作

  • query函数,得到一个单词被插入的次数
// 查询某个单词出现的
int query(char *s) {
	int p=0; // 从根节点开始查
	// 扫描字符串
	for(int i=0;s[i];i++) {
		int j=s[i]-'a'; // 转换为映射值
		if(!ch[p][j]) return 0; // 如果找不到返回0
		// 有字母s[i],则走下来
		p=ch[p][j];
	}
	// 如果能走到词尾,则返回插入次数
	return cnt[p];
}

4)完整代码

1. 字符数组

#include<bits/stdc++.h>
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

// 解题思路: 节点表示数字,边表示字符

const int N=1e5+5;
char s[N]; // 每次输入的字符串,N是每个单词的最大长度
int ch[N][26]; // ch[p][j]:从节点p沿着j这条边走到的子节点,边为26个小写字母映射值为0~25
int cnt[N]; // cnt[p]:以节点p结尾的单词的插入次数
int idx; // 遍历因子

// s:单词(字符串)
void insert(char *s) {
	int p=0; // 从根节点开始插
	// 枚举字符串每个字符
	for(int i=0;s[i];i++) {
		int j=s[i]-'a'; // a~z映射到0~25
		// 如果这个字符不是儿子节点,创建儿子,p指针再走到儿子
		if(!ch[p][j]) ch[p][j]=++idx; // 节点编号+1
		// 如果这个字符是儿子节点,p指针走到儿子节点
		p=ch[p][j];
	}
	cnt[p]++; // 以节点p结尾的单词插入的次数+1 
}

// 查询某个单词出现的
int query(char *s) {
	int p=0; // 从根节点开始查
	// 扫描字符串
	for(int i=0;s[i];i++) {
		int j=s[i]-'a'; // 转换为映射值
		if(!ch[p][j]) return 0; // 如果找不到返回0
		// 有字母s[i],则走下来
		p=ch[p][j];
	}
	// 如果能走到词尾,则返回插入次数
	return cnt[p];
}

int main() {
	int n;
	cin>>n;
	while(n--) {
		char op;
		scanf("%s%s",&op,s);
		if(op=='I') insert(s);
		else cout<<query(s)<<'\n';
	}
	return 0;
}

2. 字符串

#include<bits/stdc++.h>
#define x first
#define y second

using namespace std;

typedef long long ll;
typedef pair<int,int> PII;

// 解题思路: 节点表示数字,边表示字符

// 文件总长度不超过32K,所以总字符不超过:32K=32*1024
const int N=32*1024+10; 
char s[N]; // 每次输入的字符串,N是每个单词的最大长度
int ch[N][26]; // ch[p][j]:从节点p沿着j这条边走到的子节点,边为26个小写字母映射值为0~25
int cnt[N]; // cnt[p]:以节点p结尾的单词的插入次数
int idx; // 遍历因子

// s:单词(字符串)
void insert(string s) {
	int p=0; // 从根节点开始插
	// 枚举字符串每个字符
	for(int i=0;i<s.length();i++) {
		int j=s[i]-'A'; // a~z映射到0~25
		// 如果这个字符不是儿子节点,创建儿子,p指针再走到儿子
		if(!ch[p][j]) ch[p][j]=++idx; // 节点编号+1
		// 如果这个字符是儿子节点,p指针走到儿子节点
		p=ch[p][j];
	}
	cnt[p]++; // 以节点p结尾的单词插入的次数+1 
}

// 查询某个单词出现的
int query(string s) {
	int p=0; // 从根节点开始查
	// 扫描字符串
	for(int i=0;i<s.length();i++) {
		int j=s[i]-'a'; // 转换为映射值
		if(!ch[p][j]) return 0; // 如果找不到返回0
		// 有字母s[i],则走下来
		p=ch[p][j];
	}
	// 如果能走到词尾,则返回插入次数
	return cnt[p];
}

int main() {
//	while(scanf("%s",s)) {
//		insert(s);
//	}
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	string s;
	while(cin>>s) {
		insert(s);
	}
	cout<<idx+1; // 加上根节点
	return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Redis:使用redis-dump导出、导入、还原数据实例

redis的备份和还原&#xff0c;借助了第三方的工具&#xff0c;redis-dump 1、安装必要环境 yum -y install zlib-devel openssl-devel2、安装redis-dump 安装ruby&#xff1a; ruby下载地址&#xff1a;https://www.ruby-lang.org/zh_cn/downloads/ 我下载的是 2.5.0 版本…

Linux系统下基于VSCode和Cmake进行C++开发

目录 简介一、GCC编译器1.1创建cpp文件1.2编译过程1.3g重要编译参数 二、GDB调试器三、IDE-VScode3.1 VSCode常用快捷键3.2 swap测试 四、CMake4.1CMake介绍4.2 CMake语法特性介绍4.3 CMake重要指令和常用变量4.4 CMake编译流程4.5CMake代码实践 五、使用VSCode进行完整项目开发…

Gateway网关在url参数带有特殊字符的情况下转发失败(响应400)

本文主要分享了&#xff0c;SpringCloud Gateway网关在url参数带有空格或者特殊字符的情况下&#xff0c;转发失败导致响应错误码400的解决方案。 响应400错误码的2种场景&#xff1a; 1.参数带空格&#xff0c;Gateway会误认为该空格是切割符&#xff0c;如?phone 135****6…

B/S基于云计算的云HIS智慧医院管理系统源码带电子病历编辑器

目录 一、系统概述 二、开发环境 三、系统功能 1、门诊部分 2、住院部分 3、电子病历 4、药物管理 5、统计报表 6、综合维护 7、运营运维 云HIS系统&#xff1a;病案首页 云his系统源码 SaaS应用 功能易扩 统一对外接口管理 现如今&#xff0c;大数据、云计算、移动…

深入浅出计算机网络 day.2 概论⑥ 计算机网络体系结构

上帝疯狂杜撰世界悲情的命题 将凉薄和荒芜尽写 —— 24.3.13 内容概述 1.常见的三种计算机网络体系结构 2.计算机网路体系结构分层的必要性 3.计算机网络体系结构分层思想举例 4.计算机网络体系结构中的专用术语 一、常见的三种计算机网络体系结构 1.OSI参考模型 …

Linux第77步_处理Linux并发的相关函数

了解linux中的“原子整形数据”操作、“原子位数据”操作、自旋锁、读写锁、顺序锁、信号量和互斥体&#xff0c;以及相关函数。 并发就是多个“用户”同时访问同一个共享资源。如&#xff1a;多个线程同时要求读写同一个EEPROM芯片&#xff0c;这个EEPROM就是共享资源&#x…

运行vue项目时的问题

1.问题:在终端输入:npm run serve时&#xff0c;弹出选择应用以打开npm 2.解决方法: 在你的终端中输入&#xff1a;get-command npm&#xff08;第一次可能没反应 再输入一次&#xff09; 根据这个路径找到npm删除即可 再次运行npm run serve

谈谈你对Java平台的理解?

从你接触 Java 开发到现在&#xff0c;你对 Java 最直观的印象是什么呢&#xff1f;是它宣传的 “Write once, run anywhere”&#xff0c;还是目前看已经有些过于形式主义的语法呢&#xff1f;你对于 Java 平台到底了解到什么程度&#xff1f;请你先停下来总结思考一下。 今天…

VSCode提交代码

VSCode提交代码方式&#xff1a; 先在电脑本地文件夹中打开git的bash窗口使用git clone https://github.com/xxxx/克隆仓库地址到本地&#xff0c;并生成一个项目的文件夹打开VSCode&#xff0c;点击文件按钮&#xff0c;打开加载项目的文件夹对于VSCode设置Git路径&#xff…

【小黑嵌入式系统第十九课】结课总结(三)——操作系统部分(RTOSμC/OS-Ⅲ程序设计基础(任务函数时间临界区通信))

上一课&#xff1a; 【小黑嵌入式系统第十八课】结课总结&#xff08;二&#xff09;——软件部分&#xff08;系统架构&调试&测试&运行&系统软件设计&#xff09; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0…

迷你洗衣机排名前十名:2024年十大性能超强内衣洗衣机优选

随着现在的生活水平的不断提高&#xff0c;高科技能帮我们搞定不少问题&#xff0c;如果你比较注重个人卫生、追求生活品质&#xff0c;可以考虑选择一台专用的迷你洗衣机&#xff0c;我们就无须自己亲自动手去清洗内衣物&#xff0c;从而导致浪费时间&#xff0c;如果你担心孩…

Docker常见指令

1.docker search mysql &#xff1a;从docker镜像仓库搜索和mysql有关的镜像 docker search mysql 2.docker pull mysql &#xff1a;从docker仓库拉取mysql镜像 docker pull mysql 3.docker run mysql &#xff1a;启动mysql镜像 docker run mysql 4.docker ps &#xff…

iconfont 字体应用

1、登录 打开阿里图标 https://www.iconfont.cn/ 2、选择心仪的图标制作 iconfont 字体。 3、图标全部选择入库之后&#xff0c; 点右上角的购物车。 添加到项目&#xff0c;是方便管理图标字体的。 也可以直接下载代码的 4、下载到本地之后&#xff0c;把里面的 iconfont.…

altgraph的安装和用途说明

前言 altgraph 是 graphlib 的一个分支&#xff1a;一个图&#xff08;网络&#xff09;包&#xff0c;用于构建图、BFS 和 DFS 遍历、拓扑排序、最短路径等&#xff0c;带有 graphviz 输出。 安装 pip install altgraph 函数和用例 生物链 from altgraph import Graph# 定…

linux查看服务器登录成功和登录失败的命令

last 查看成功登录服务器的信息&#xff0c;包括ip&#xff0c;时间&#xff0c;登录用户&#xff0c;时长。lastb 查看登录服务器失败的信息。 last命令实例&#xff1a; 其他参数&#xff1a; -a&#xff1a;把从何处登入系统的主机名称或ip地址&#xff0c;显示在最后一行…

软件设计师16--段页式存储

软件设计师16--段页式存储 考点1&#xff1a;页式存储存储管理 - 页式存储组织存储管理 - 页面置换算法例题&#xff1a; 考点2&#xff1a;段式存储存储管理 - 段式存储组织例题&#xff1a; 考点1&#xff1a;页式存储 存储管理 - 页式存储组织 页式存储&#xff1a;将程序…

MySQL数据表的增删改查(基础)(CRUD)

1.CRUD 注释&#xff1a;在SQL中可以使用“--空格描述”来表示注释说明. CRUD 即增加(Create)、查询(Retrieve)、更新(Update)、删除(Delete)四个单词的首字母缩写. 2.新增(Create) 语法: insert into 表名 values (值,值...); into --可以省略; values -- 关键字. 下面以一…

IDEA编写各种WordCount运行

目录 一、编写WordCount(Spark_scala)提交到spark高可用集群 1.项目结构 2.导入依赖 3.编写scala版的WordCount 4.maven打包 5.运行jar包 ​6.查询hdfs的输出结果 二、本地编写WordCount(Spark_scala)读取本地文件 1.项目结构 2.编写scala版的WordCount 3.编辑Edit …

HDFS的架构优势与基本操作

目录 写在前面一、 HDFS概述1.1 HDFS简介1.2 HDFS优缺点1.2.1 优点1.2.2 缺点 1.3 HDFS组成架构1.4 HDFS文件块大小 二、HDFS的Shell操作&#xff08;开发重点&#xff09;2.1 基本语法2.2 命令大全2.3 常用命令实操2.3.1 上传2.3.2 下载2.3.3 HDFS直接操作 三、HDFS的API操作3…

influxdb2使用

&#xff08;作者&#xff1a;陈玓玏&#xff09; influxdb2首次使用时&#xff0c;通过k8s部署的&#xff0c;所以进入pod内部执行命令。 先在k8sdashboard找到influx的pod&#xff0c;点击执行&#xff0c;即可进入命令行界面。 首次连接时&#xff0c;通过influx setup启动…