Trie(算法版)

devtools/2025/1/21 0:05:44/
#include <iostream>using namespace std;const int N=100010;
int son[N][26],cnt[N],idx;
//son记录trie数,cnt记录每个词出现的次数,idx记录每个字符所占⽤的下标//加入字符串
void add(char str[]){//idx = 0既表⽰根节点也表⽰空节点int p =0;for(int i =0;str[i];i++){  //字符串末尾为0int u = str[i]-'a';if(!son[p][u]){son[p][u]= ++idx;//当前字符不存在,增加}p=son[p][u];  //向下继续遍历}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;//若没找到,直接返回0}p=son[p][u];}return cnt[p];  //p指向字符串的最后一个字符
}int main(){int n;cin>>n;while(n--){char op;char x[N];cin>>op>>x;if(op=='I')add(x);else cout<<query(x)<<endl;}return 0;}

假设情境 1096:我们有一个 Trie 树,开始时是空的。我们现在要插入以下两个单词:cat 和 car。

 

初始状态:

 
  • idx:初始值为 0,表示根节点。
  • son [N][26]:所有元素初始值为 0,表示 Trie 树是空的。
 

插入 “cat”:

 
  1. 字符 'c':
    • 计算索引 u = 'c' - 'a' = 2。
    • 检查 son [0][2],因为 Trie 树是空的,所以 son [0][2] 为 0。由于 son [0][2] 为 0,意味着当前节点 0 没有对应字符 'c' 的子节点。因此,我们创建一个新节点 1,并将 son [0][2] 设为 1,表示根节点 0 的 'c' 子节点是节点 1。
    • 然后,将 p 更新为 1,即移动到节点 1。
    • idx 增加到 1。
  2. 字符 'a':
    • 计算索引 u = 'a' - 'a' = 0。
    • 检查 son [1][0],此时 son [1][0] 仍为 0,因为之前还没有插入任何以 'a' 为第二个字符的单词。
    • 因此,我们创建一个新节点 2,并将 son [1][0] 设为 2。
    • 将 p 更新为 2,现在指向节点 2。
    • idx 增加到 2。
  3. 字符 't':
    • 计算索引 u = 't' - 'a' = 19。
    • 检查 son [2][19],此时 son [2][19] 为 0,因为还没有插入任何以 't' 为第三个字符的单词。
    • 创建新节点 3,并将 son [2][19] 设为 3。
    • p 更新为 3,现在指向节点 3。
    • idx 增加到 3。
    • 此时,已成功插入 “cat”。p 当前指向节点 3,在 cnt [3] 上加 1,表示有一个单词以 't' 结尾。
 

再插入 “car”:

 
  1. 字符 'c':
    • 计算索引 u = 'c' - 'a' = 2。
    • 检查 son [0][2],此时 son [0][2] 为 1,表示根节点已经有一个 'c' 子节点,指向节点 1。
    • 直接将 p 更新为 1,不用创建新节点。
  2. 字符 'a':
    • 计算索引 u = 'a' - 'a' = 0。
    • 检查 son [1][0],此时 son [1][0] 为 2,表示节点 1 有一个 'a' 子节点,指向节点 2。
    • 将 p 更新为 2。
  3. 字符 'r':
    • 计算索引 u = 'r' - 'a' = 17。
    • 检查 son [2][17],此时 son [2][17] 为 0,因为还没有插入任何以 'r' 为第三个字符的单词。
    • 创建新节点 4,并将 son [2][17] 设为 4。
    • p 更新为 4。
    • idx 增加到 4。
    • 现在已成功插入 “car”。p 当前指向节点 4,在 cnt [4] 上加 1,表示有一个单词以 'r' 结尾。
 

总结:
每当我们遇到一个新的字符且当前节点没有对应的子节点时(即 son [p][u] 为 0),我们就需要创建一个新的节点,并更新 son [p][u] 为新节点的编号。同时,idx 自增,用于分配新节点的编号。通过这种方式,Trie 树可以动态地构建,插入和查询操作都能高效完成。


http://www.ppmy.cn/devtools/152220.html

相关文章

Windows11电脑总是一闪一闪的,黑一下亮一些怎么解决

Windows11电脑总是一闪一闪的&#xff0c;黑一下亮一些怎么解决 1. 打开设备管理器2. 点击显示适配器3. 更新下方两个选项的驱动3.1 更新驱动Inter(R) UHD Graphixs3.2 更新驱动NVIDIA GeForce RTX 4060 Laptop GPU 4. 其他文章快来试试吧&#x1f970; 1. 打开设备管理器 在电…

数据库3(MySQL版)

1.任务要求 (1).分别查询student表和score表的所有记录 (2).查询student表的第2条到5条记录 (3).从student表中查询计算机系和英语系的学生的信息 (4).从student表中查询年龄小于22岁的学生信息 (5).从student表中查询每个院系有多少人 (6).从score表中查询每个科目的最高分 (7…

废品回收小程序,数字化回收时代

随着科技的不断创新发展&#xff0c;废品回收在各种技术的支持下也在不断地创新&#xff0c;提高了市场的发展速度&#xff0c;不仅能够让回收效率更加高效&#xff0c;还能够让居民更加便捷地进行回收&#xff0c;推动废品回收行业的发展。 回收市场机遇 目前&#xff0c;废…

三天急速通关Java基础知识:Day1 基本语法

三天急速通关JAVA基础知识&#xff1a;Day1 基本语法 0 文章说明1 关键字 Keywords2 注释 Comments2.1 单行注释2.2 多行注释2.3 文档注释 3 数据类型 Data Types3.1 基本数据类型3.2 引用数据类型 4 变量与常量 Variables and Constant5 运算符 Operators6 字符串 String7 输入…

WPF实现动态四宫格布局

需求描述 我们要设计一个界面&#xff0c;用户可以通过 CheckBox 控制哪些图表显示。图表的数量是动态的&#xff0c;最多可以选择显示四个图表。如果显示一个图表&#xff0c;它会占满整个区域&#xff1b;如果显示两个图表&#xff0c;它们会水平排列&#xff1b;显示三个图…

【前端】CSS学习笔记(1)

目录 CSS的简介CSS的概念语法 CSS的引入方式内联样式&#xff08;行内样式&#xff09;内部样式外部样式&#xff08;推荐&#xff09; 选择器全局选择器元素选择器类选择器ID选择器合并选择器后代选择器子选择器相邻兄弟选择器通用兄弟选择器伪类选择器:link:visited:hover:ac…

【客观对比】激光雷达 vs 纯视觉方案:汽车自动驾驶的两种路径

激光雷达 vs 纯视觉方案&#xff1a;汽车自动驾驶的两种路径 导语 汽车自动驾驶技术正以惊人的速度发展&#xff0c;未来无疑会彻底改变我们的出行方式。在这场技术竞争中&#xff0c;激光雷达&#xff08;LiDAR&#xff09;和纯视觉&#xff08;Camera-based&#xff09;方案…

青少年编程与数学 02-007 PostgreSQL数据库应用 09课题、规则、约束和默认值

青少年编程与数学 02-007 PostgreSQL数据库应用 09课题、规则、约束和默认值 一、规则二、规则应用示例示例1&#xff1a;使用规则实现视图示例2&#xff1a;使用规则自动填充数据示例3&#xff1a;使用规则实现数据的合并插入 三、约束四、约束应用示例示例1&#xff1a;主键约…