首页 > 其他分享 >Trie树 - 知识点梳理

Trie树 - 知识点梳理

时间:2023-07-11 09:00:48浏览次数:35  
标签:知识点 cur Trie len int 查找 str ind 梳理

介绍

Trie 树,又名字典树,顾名思义就是为多个字符串的存贮与查找而生的,和现实中的字典差不多,其实就是一种字符查找自动机。通过对被查找串预处理,梳理为树形结构,在每次查找 \(S\) 时复杂度可以达到 \(O(|S|)\)(而朴素查找复杂度为 \(O(|S| + \sum_i |t_i|)\)),且占的空间比单独存贮字符串通常要小。

实现方法

朴素情况下,我们查找字符串时会与每个字符串进行比较,从第一个字符开始,然后比较第二个,依次往后。如果我们把每个字符串抽象成一条链,查找时我们就是从链头依次往后走,看能不能走到头。(其实一条链就是一个简易的 Trie 树)

而如果是有多个被匹配串,朴素的做法是逐个匹配,也就是在每个链上都跑一遍。
注意到这样我们每次匹配时同个匹配串走的路径是相同的。
于是我们可以把相同前缀的被匹配串的前缀节点合并,这就形成了一棵树。
每次插入时我们顺着已有的路往下走,若没有路了再新建节点。
注意我们需要在链的末尾进行标记,表示有被匹配串以该节点结尾。

这样查找时我们按照查找串的路线往下走,如果能走到底而且尾部节点有标记就表明存在相同的被查找串。

这样就解决了问题。
上代码! (这里使用了递归的写法,简单快捷)

const int MAXN = 500005;
int s[MAXN][27], n, m, cnt, col[MAXN]; // s: 儿子节点  cnt: 栈顶指针  col: 节点标记 
int insert (int cur, const char *str, int len, int ind) { // cur: 当前节点编号   str: 插入的被查找串   len: 被查找串长度  ind: 当前下标 
	if (!cur) cur = ++cnt;
	if (ind < len) {
		s[cur][str[ind]-'a'] = insert(s[cur][str[ind]-'a'], str, len, ind + 1); 
	}
	else col[cur] = 1;
	return cur; 
}
bool find (int cur, const char *str, int len, int ind) {
	if (!cur) return false;
	if (len == ind) return col[cur];
	return find (s[cur][str[ind]-'a'], str, len, ind + 1);
}

例题

超级无敌大板子 Luogu P2580 于是他错误的点名开始了
直接套板子即可。

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 500005;
int s[MAXN][27], n, m, cnt, col[MAXN]; // s: 儿子节点  cnt: 栈顶指针  col: 节点标记 
int insert (int cur, const char *str, int len, int ind) { // cur: 当前节点编号   str: 插入的被查找串   len: 被查找串长度  ind: 当前下标 
	if (!cur) cur = ++cnt;
	if (ind < len) {
		s[cur][str[ind]-'a'] = insert(s[cur][str[ind]-'a'], str, len, ind + 1); 
	}
	else col[cur] = 1;
	return cur; 
}
bool find (int cur, const char *str, int len, int ind) {
	if (!cur) return false;
	if (len == ind) return col[cur];
	return find (s[cur][str[ind]-'a'], str, len, ind + 1);
}

int root1, root2;
char tmp[55];
int main () {
	root1 = ++cnt;
	root2 = ++cnt;
	cin >> n;
	for (int i = 1;i <= n;i++) {
		cin >> tmp;
		insert(root1, tmp, strlen(tmp), 0);
	}
	cin >> m;
	for (int i = 1;i <= m;i++) {
		cin >> tmp;
		if (!find (root1, tmp, strlen(tmp), 0)) cout << "WRONG" << endl;
		else if (!find(root2, tmp, strlen(tmp), 0)) cout << "OK" << endl, insert(root2, tmp, strlen(tmp), 0);
		else cout << "REPEAT" << endl;
	}
	return 0;
}

标签:知识点,cur,Trie,len,int,查找,str,ind,梳理
From: https://www.cnblogs.com/mindeveloped/p/17542855.html

相关文章

  • jvm学习-垃圾回收的一些知识点
    部分图片和描述来自参考资料,非原创对象回收处理过程如何标定对象是否存活两种方法:引用计数方法可达性分析算法引用计数方法就和ReentrantLock可重入锁一样,内部维系着一个state,当同个线程重入结束后就会归零,但是这种方法有点问题publicstaticvoidte......
  • labview和西门子plc通信 知识点和领域范围:LabVIEW、西门子PLC、
    labview和西门子plc通信知识点和领域范围:LabVIEW、西门子PLC、通信LabVIEW是一种图形化编程环境,用于控制和测量系统的设计和开发。它提供了一个直观的界面,使工程师能够通过拖放和连接图标来创建程序。西门子PLC(可编程逻辑控制器)是一种常用的工业自动化设备,用于控制和监控生产过程......
  • 科目一知识点,自己写着玩~
    C1 可以开C2C3C4新政策说的C6 指的是轻型牵引挂车  年龄适用范围为:20~60周岁 且必须有小型汽车、小型自动挡汽车驾驶证一年以上资质。小型汽车的年龄要求:18周岁~~无上限。另外要说的一点是:70岁以上的人群考驾照要经过记忆力、判断力、反应力的测试,每年都要体检。而......
  • [模板]01trie,维护异或最大值
    //查询异或最大值,每次插入和查询时间都是log(C)template<classT>classtrie01{vector<vector<T>>tree;public:trie01():tree(1,vector<T>(2,0)){}//插入待检查的数字voidinsert(Tx){intp=0;for(inti=sizeof......
  • MySQL常用知识点总结
    MySQL常用知识点总结参考地址:(https://maifile.cn/est/a3206887806899/pdf)【一】知识点总结【二】多表查询【三】常用函数【四】Excel数据清洗......
  • Multi-Modal Attention Network Learning for Semantic Source Code Retrieval 解读
    Multi-ModalAttentionNetworkLearningfor SemanticSourceCodeRetrieva Multi-ModalAttentionNetworkLearningfor SemanticSourceCodeRetrieval,题目意思是用于语义源代码检索的多模态注意网络学习,2019年发表于ASE的##研究什么东西Background:研究代码检索技......
  • Linux下路由配置梳理
    转自  散尽浮华  在日常运维作业中,经常会碰到路由表的操作。下面就linux运维中的路由操作做一梳理:------------------------------------------------------------------------------先说一些关于路由的基础知识:1)路由概念路由: 跨越从源主机到目标主机的一个互联网络来转......
  • 使用vue-super-flow的使用进行工作流的梳理
    1.安装依赖npminstallvue-super-flow2.在页面中引用<template><super-flow></super-flow></template><script>importSuperFlowfrom'vue-super-flow'import'vue-super-flow/lib/index.css'exportdefault{......
  • Jmeter学习之三_知识梳理
    Jmeter学习之三_知识梳理背景简单学习了Jmeter的两个用例感觉可以继续深入学习一下Jmeter了.所以想着趁体检入职之前继续学习完善一下.希望能够继续提高Jmeter的相关知识1.什么是Jmeter?ApacheJMeter,是一个100%纯Java的开源软件,旨在加载测试功能行为和测量性能。它......
  • umi+antd语法知识点学习
    前言:新建一个前端工程,有好多知识点需要学习。查资料的知识点如下  1,React.FC详细解说泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。1.React.FC是一个函数式组件,是在TypeScript使用一个泛型,FC就是FunctionComponent......