字典树(trie树)详解

【本文概要】本文主要介绍了字典树的概念,字典树的一般算法,包括初始化,插入,查找等,最后举了比较典型的案例来辅助理解字典树这种特殊的数据结构。

1、什么是字典树

        字典树,是一种特殊的树状数据结构,对于解决字符串相关问题非常有效。一般而言,我们认为字典树是一种前缀树,但有时它也可以是后缀树(具体见下图)。字典树在统计、保存大量字符串中有着极大的优势:它利用字符串的公共前缀或后缀来减少查询时间,最大限度地减少不必要的字符串比较,使得查询的效率比一般算法高得多。

        如上图所示,常见的字典树的每一个节点是由一个数据域(用来标记是否在此处有字符串终止)与一个长度为26的指针域(表示26个小写字母)组成。一般我们在根结点不存储任何数据,这样是为了可以存储所有的字符串,从根结点到某一个节点,路过的字符连起来就是该节点对应的字符串。由于每个节点的子节点字符不同,也就是说明找到对应单词、字符是唯一的。

2、字典树的实现

        这里我们整理字典树的定义、插入和查找的相应算法的写法。

2.1 字典树的定义

const int size = 26;
struct Node {
	bool k; // true表示有字符串在此结尾,false表示无字符串在此结尾
	Node* next[size];

	Node() :k(false) { // 给成员变量赋值false
		for (int i = 0; i < size; ++i) {
			next[i] = nullptr; // 初始化都是空指针
		}
	}
};

2.2 字典树的插入

void insert_ch(char *ch) {
	Node *p = head;
	for (int i = 0; ch[i]; ++i) {
		if (p->next[ch[i] - 'a'] == nullptr) // 判断下层节点是否存在
			p->next[ch[i] - 'a'] = new Node; // 开辟新空间
		p = p->next[ch[i] - 'a'];
	}
	p->k = true; // 进行字符串结尾标记
}

        每次从根节点进行插入,如果向下的节点已经存在,就直接读取,否则拓展一个新节点。之后将最后一个节点的k标记为true表示该位置有一个字符串结尾。

2.3 字典树的查找

bool find_ch(char *ch) {
	Node *p = head;
	for (int i = 0; ch[i]; ++i) {
		if (p->next[ch[i] - 'a'] == nullptr) { // 判断下层节点是否存在
			return false; // 不存在即判否
		}
		p = p->next[ch[i] - 'a'];
	}
	return p->k; // 最终判断
}

        基本过程与插入相同,向下查找,入过该节点不存在,直接返回false,如果存在一直向下查找,最终返回末尾标记的k。

3、关于字典树的常见问题整理

3.1 依依的瓶中信

//本题考察字典树的扩展应用
//其具体算法仍是字典树的插入与查询
//需要注意的是当前字符串不能与自己匹配,
//解决的方法是写一个删除函数,先将当前字符串删除再查询,查询后再恢复 
//由于插入与删除的本质相同,只是cnt数组对应位置的增加或减小,故只需改写插入函数即可 
#include <bits/stdc++.h>

using namespace std;

const int maxn=1e5+100;

string str[maxn];//存储原始字符串组 
int nex[maxn][27];//nex[x][0]表示从第x个结点出发,边为'a'的下一个结点地址 
int cnt[maxn];//cnt[i]表示以第i个结点结尾的前缀的数量 
int idx=2;//用于动态开点 

void Insert(string s,int tag)//将字符串s插入字典树中,或将其从字典树中删除
//若传入tag=1,则为插入;若传入tag=-1,则为删除
//插入与删除的本质是令对应的cnt[x]+1或-1 
{
    int x=1;//初始从根结点(1号)开始 
    for(int i=0;i<s.size();i++)//遍历字符串s 
    {
        cnt[x]+=tag;//对每个字符,以该字符结尾的前缀数量均+1/-1 
        if(nex[x][s[i]-'a']==0)//若该字符(存储该字符的边)未被记录 
        {
            nex[x][s[i]-'a']=idx++;//则动态开点并记录之 
        }
        x=nex[x][s[i]-'a'];//继续向下追溯 
    }        
    cnt[x]+=tag;//结尾字符对应的前缀数量+1/-1 
}

int Search(string s)//在字典树中查找与s最接近的字符串,并返回匹配的最长前缀的长度 
{
    int x=1;//初始从根结点(1号)开始 
    int ans=0;//记录匹配的最长前缀的长度 
    for(int i=0;i<s.size();i++)//遍历字符串 
    {
        if(nex[x][s[i]-'a']==0)//已经无法再匹配(不存在记录当前字符的边)
        {
            return ans;//返回之前累计的长度 
        }    
        x=nex[x][s[i]-'a'];//若能继续匹配,则继续向下追溯 
        if(cnt[x]==0)return ans;//已经不存在以x结点结尾的前缀,返回之前累计的长度
        //注意以上这句不可省略,因为在删除操作中只是减少了字符串出现的次数,并没有删除之前记录的字符 
        ans++;//计数值加1,重复上述操作 
    }    
    return ans;//最终返回ans 
}

int main()
{
    int N;
    cin>>N;
    for(int i=0;i<N;i++)//输入N个字符串 
    {
        cin>>str[i];
        Insert(str[i],1);//插入 
    }
    for(int i=0;i<N;i++)//N组查询 
    {
        Insert(str[i],-1);//先将当前字符串删除 
        cout<<Search(str[i])<<endl;//查询匹配的最长前缀的长度并输出 
        Insert(str[i],1);//将当前字符串重新插入以恢复字典树 
    }
    return 0;
}

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

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

相关文章

从CL1看生物计算机的创新突破与发展前景:技术、应用与挑战的多维度剖析

一、引言 1.1 研究背景与意义 随着科技的飞速发展&#xff0c;计算机技术已经成为推动现代社会进步的核心力量之一。从最初的电子管计算机到如今的大规模集成电路计算机&#xff0c;计算机的性能得到了极大的提升&#xff0c;应用领域也不断拓展。然而&#xff0c;传统计算机…

小兔鲜Vue3

counterStore里面包含着对象返回的东西。 getters就是conputer git initgit add .git commit -m " " jsconfig进行路径提示。vite.config.js进行实际路径转化。 第一个文件做好就是一个axios实例了&#xff0c;可以直接调用方法。 在第二个文件是实例.get 写好路…

驱动 AI 边缘计算新时代!高性能 i.MX 95 应用平台引领未来

智慧浪潮崛起&#xff1a;AI与边缘计算的时代 正悄然深植于我们的日常生活之中&#xff0c;无论是火热的 ChatGPT 与 DeepSeek 语言模型&#xff0c;亦或是 Meta 智能眼镜&#xff0c;AI 技术已经无形地影响着我们的生活。这股变革浪潮并未停歇&#xff0c;而是进一步催生了更高…

STM32之软件SPI

SPI传输更快&#xff0c;最大可达80MHz&#xff0c;而I2C最大只有3.4MHz。输入输出是分开的&#xff0c;可以同时输出输入。是同步全双工。仅支持一主多从。SS是从机选择线。每个从机一根。SPI无应答机制的设计。 注意&#xff1a;所有设备需要共地&#xff0c;时钟线主机输出&…

深度学习系列79:Text2sql调研

参考 https://github.com/topics/text-to-sql 这里是一些资源&#xff1a;https://github.com/eosphoros-ai/Awesome-Text2SQL/blob/main/README.zh.md 这里是综述文章&#xff1a;https://zhuanlan.zhihu.com/p/647249972 1. 数据集 Spider: 一个跨域的复杂text2sql数据集&a…

【Unity】 HTFramework框架(六十一)Project窗口文件夹锁定器

更新日期&#xff1a;2025年3月7日。 Github源码&#xff1a;[点我获取源码] Gitee源码&#xff1a;[点我获取源码] 索引 Project窗口文件夹锁定器框架文件夹锁定自定义文件夹锁定限制条件 Project窗口文件夹锁定器 在Project窗口中&#xff0c;文件夹锁定器能够为任何文件夹加…

nginx服务器实现上传文件功能_使用nginx-upload-module模块

目录 conf文件内容如下html文件内容如下上传文件功能展示 conf文件内容如下 #user nobody; worker_processes 1;error_log /usr/logs/error.log; #error_log /usr/logs/error.log notice; #error_log /usr/logs/error.log info;#pid /usr/logs/nginx.pid;even…

基于云的内容中台核心优势是什么?

弹性云架构赋能资源整合 现代企业通过弹性云架构实现多源数据资源的深度整合&#xff0c;其动态扩展能力可自动适配业务流量波动。基于分布式存储与容器化部署&#xff0c;系统能够无缝对接CRM、ERP等企业软件集成&#xff0c;实现跨平台数据实时同步。值得注意的是&#xff0…

*图论基础(5)

持续更新... 1.图的基本概念 不写了&#xff0c;网上有好多资料ovo 2.图的存储和遍历 2.1存储&#xff1a; 3.最小生成树 3.2Kruskal算法 4.拓扑排序 拓扑排序的⽬标是将有向⽆环图中的所有结点排序&#xff0c;使得排在前⾯的结点不能依赖于排在后⾯的结 点。在课程问题中…

DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)示例3: 行选择

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 Deep…

DevSecOps CI/CD 管道中数字供应链安全的集成策略

前言&#xff1a; 在敏捷开发的模式下&#xff0c;应用程序会通过 DevSecOps 的敏捷软件开发生命周期&#xff08;SDLC&#xff09;范式进行开发&#xff0c;并使用持续集成/持续交付&#xff08;CI/CD&#xff09;管道的流程。 然而&#xff0c;在软件开发、供应和交付运营中…

JmeterHttp请求头管理出现Unsupported Media Type问题解决

JmeterHttp请求头管理出现Unsupported Media Type问题解决 大多数的app与pc端压测的时候都会出现这种情况 当我们在jemter测试当中当中遇见Unsupported Media Type&#xff0c;有一种可能就是我们请求的网页的content-Type的类型与我们测试的时候的类型不一致 解决方法 可以添…

STM32 子设备通过CAN发送数据到主设备

采集ADC、GPS经纬坐标、温湿度数据、大气压数据通过CAN方式发送给主设备端&#xff0c;帧ID按照如下定义&#xff1a; 我尼玛一个标准帧ID位数据是11位&#xff0c;扩展帧才是111829位&#xff0c;它说最开头的是四位是真类型&#xff0c;并给我如下解释&#xff1a; 它把帧的定…

基于深度学习的青花瓷图像检索系统开发与实现

目录 1.研究背景与目的 1.1课题背景 1.2研究目的 二、调研资料情况 2.1图像分割研究现状 2.2图像检索调研 2.2.1选择深度学习进行检索的原因及优势 2.2.2基于深度学习的图像检索技术的发展 2.2.3基于深度学习的图像检索的研究重点 2.3基于深度学习的图像检索方法调研 …

FreeRTOS学习(七):通过实例深入理解栈的作用(二)

FreeRTOS学习&#xff08;七&#xff09;&#xff1a;通过实例深入理解栈的作用&#xff08;二&#xff09; 文章目录 FreeRTOS学习&#xff08;七&#xff09;&#xff1a;通过实例深入理解栈的作用&#xff08;二&#xff09;前言一、栈的深度局部变量调用深度 总结 前言 看…

[傻瓜式教学]如何将MathType公式编辑器内嵌到WPS工具栏中

[傻瓜式教学]如何将MathType公式编辑器内嵌到WPS工具栏中 将MathType公式编辑器内嵌到WPS工具栏中 下载好所需文件 我用夸克网盘分享了「mathtype安装教程超简单易上手.zip」&#xff0c;点击链接即可保存。打开「夸克APP」 链接&#xff1a;https://pan.quark.cn/s/4726c684…

网络安全整改措施复函

&#x1f345; 点击文末小卡片 &#xff0c;免费获取网络安全全套资料&#xff0c;资料在手&#xff0c;涨薪更快 以计算机安全的主要因素为突破口&#xff0c;重点防范各种不利于计算机网络正常运行的措施&#xff0c;从不同角度全面了解影响计算机网络安全的情况&#xff0c;…

基于大数据的全国地铁数据可视化分析系统

【大数据】基于大数据的全国地铁数据可视化分析系统&#xff08;完整系统源码开发笔记详细部署教程&#xff09;✅ 目录 一、项目简介二、项目界面展示三、项目视频展示 一、项目简介 &#x1f31f; 技术特点✔️ PythonFlask黄金架构&#xff0c;Bootstrap塑造友好交互界面 ✔…

react 和 react-dom

react开发的时候&#xff0c;一般下载两个包&#xff0c;一个是react&#xff0c;一个是react-dom&#xff0c;其中react是react的核心代码。 react只包含了web和Mobile通用的核心部分&#xff0c;Dom操作在react-dom中&#xff0c;Mobile在react-native中&#xff1b;react的核…

安科瑞新能源充电桩解决方案:驱动绿色未来,赋能智慧能源

安科瑞顾强 引言 在“双碳”目标与新能源汽车产业高速发展的双重驱动下&#xff0c;充电基础设施正成为能源转型的核心环节。安科瑞电气股份有限公司凭借在电力监控与能效管理领域20余年的技术积淀&#xff0c;推出新一代新能源充电桩解决方案&#xff0c;以智能化、高兼容性…