当前位置: 首页 > news >正文

自然语言处理学习笔记(六)————字典树

目录

1.字典树

(1)为什么引入字典树

(2)字典树定义

(3)字典树的节点实现

(4)字典树的增删改查

DFA(确定有穷自动机)

(5)优化


1.字典树

(1)为什么引入字典树

        匹配算法的瓶颈之一在于如何判断集合(词典)中是否含有字符串。如果用有序集合TreeMap)的话,复杂度是o(logn) ( n是词典大小);如果用散列表( Java的HashMap. Python的dict )的话,账面上的时间复杂度虽然下降了,但内存复杂度却上去了。有没有速度又快、内存又省的数据结构呢?这就是字典树。

(2)字典树定义

        字符串集合常用字典树存储,这是一种字符串上的树形数据结构。字典树中每条边都对应一个字,从根节点往下的路径构成一个个字符串。字典树并不直接在节点上存储字符串,而是将词语视作根节点到某节点之间的一条路径,并在终点节点上做个标记"该节点对应词语的结尾".字符串就是一条路径,要查询一个单词,只需顺着这条路径从根节点往下走。如果能走到特殊标记的节点,则说明该字符串在集合中,否则说明不存在。一个典型的字典树如下图所示所示。

         其中,蓝色标记着该节点是一个词的结尾,数字是人为的编号。按照路径我们可以得到如下表所示:

词语路径
入门0-1-2
自然0-3-4
自然人0-3-4-5
自然语言0-3-4-6-7
自语0-3-8

        当词典大小为 n 时,虽然最坏情况下字典树的复杂度依然是O(logn) (假设子节点用对数复杂度的数据结构存储,所有词语都是单字),但它的实际速度比二分查找快。这是因为随着路径的深入,前缀匹配是递进的过程,算法不必比较字符串的前缀。 

(3)字典树的节点实现

        我们要用python类来实现字典树,首先要想明白字典树的基本性质,对于每个节点来说,我们需要知道它对应的子节点和对应的边。如果要实现映射的话,还需要知道自己对应的值。·约定用值为None表示节点不对应词语,虽然这样就不能插入值为None的键了,但实现起来更简单。在_add_child方法中,先检查是否已经存在字符char对应的child,然后根据overwrite来决定是否覆盖child的值。通过这样,就可以把子节点连接到父节点上去。

class Node(object):def __init__(self, value):self._children = {} # 表示该节点下的分支(孩子,子节点)有哪些,用字典存储:char为键,表示子节点的字。字典的值为分支位置self._value = value # 理解为节点对应的值,value相当于表示从根节点到这里这是个词,不是词的话就是none,没有含义。def _add_child(self, char, value, overwrite=False):  # overwrite为true就是重写,false就是不重写。child = self._children.get(char)  # 得到该节点在char这条边的子节点if child = None:                  # 如果该节点在这个char这没有分支child = Node(value)           # 则新建一个char的分支self._children[char] = child  # 把父节点的char分支位置对应到新建的节点位置,这样就连接起来了。elif overwrite:child._value = value # 重写overwrite覆盖掉原来的值return child  # 返回的是child node的位置,即子节点位置

视频:  0203字典树Node_哔哩哔哩_bilibili 0203字典树Node_哔哩哔哩_bilibili 

比如在字典树中插入“入门”词语 

插入“自然人”词语 

插入“自然”词语

(4)字典树的增删改查

        "删改查"其实是一回事,都是查询。删除操作就是将终点的值设为None而已,修改操作无非是将它的值设为另一个值而已。从确定有限状态自动机的角度来讲,每个节点都是一个状态,状态表示当前已查询到的前缀。,从父节点到子节点的转移可以看作一个事件(状态转移)。我们向父节点查询是否有满足状态的边,如果有,则转移状态,当全部转移后,我们会询问该节点(状态)是否为蓝色节点,若是,则查询成功。

DFA(确定有穷自动机)

概念:从一个状态通过一系列事件转换到另一个状态

 【过程】:

  • 初始状态为空,当触发事件“匹”时转换到状态“匹”;
  • 触发事件“配”,转换到状态“匹配”;
  • 依次类推,直到转换为最后一个状态“匹配关键词”。

        ”增加键值对“其实还是查询,只不过在状态转移失败的时候,则创建相应的子节点,保证转移成功。

字典树的完整实现如下:

# 继承于上面的node类
class Trie(Node):# _init_可理解为“构造函数”,在对象初始化的时候调用,使用传入的参数初始化该实例。def __init__(self) -> None:super().__init__(None)# _contains_用于自定义容器类型,定义调用in和 not in来测试成员是否存在的时候所产生的行为。def __contains__(self, key):return self[key] is not None # is not None语法可以认为判断一个变量是否为None# __getitem_用于自定义容器类型,定义当某一项被访问时,使用 self[key]所产生的行为。def __getitem__(self, key):state = selffor char in key:state = state._children.get(char)if state is None:return Nonereturn state._value# _setitem_用于自定义容器类型,定义执行 self[key]=value 时产生的行为。def __setitem__(self, key, value):state = self# enumerate() 函数用于将一个可遍历的数据对象(如列表、元组或字符串)组合为一个索引序列,同时列出数据和数据下标,一般用在 for 循环当中。for i, char in enumerate(key):  if i < len(key) - 1:state = state._add_child(char, None, False)else:state = state._add_child(char, value, True)

测试:

if __name__ == '__main__':trie = Trie()# 增trie['自然'] = 'nature'trie['自然人'] = 'human'trie['自然语言'] = 'language'trie['自语'] = 'talk    to oneself'trie['入门'] = 'introduction'assert '自然' in trie   # assert是python断言语法,用于判断一个表达式,在表达式条件为 false 的时候触发异常。# 删trie['自然'] = Noneassert '自然' not in trie# 改trie['自然语言'] = 'human language'assert trie['自然语言'] == 'human language'# 查assert trie['入门'] == 'introduction'

(5)优化

        字典树的数据结构在以上的切分算法中已经很快了,但还有一些基于字典树的算法改进,把分词速度推向了千万字每秒的级别,主要按照以下递进关系优化:

  • 首字散列其余二分的字典树
  • 双数组字典树
  • AC自动机(多模式匹配)
  • 基于双数组字典树的AC自动机

相关文章:

自然语言处理学习笔记(六)————字典树

目录 1.字典树 &#xff08;1&#xff09;为什么引入字典树 &#xff08;2&#xff09;字典树定义 &#xff08;3&#xff09;字典树的节点实现 &#xff08;4&#xff09;字典树的增删改查 DFA&#xff08;确定有穷自动机&#xff09; &#xff08;5&#xff09;优化 1.…...

WPF实战项目十一(API篇):待办事项功能api接口

1、新建ToDoController.cs继承基础控制器BaseApiController&#xff0c;但是一般业务代码不写在控制器内&#xff0c;业务代码写在Service&#xff0c;先新建统一返回值格式ApiResponse.cs&#xff1a; public class ApiResponse{public ApiResponse(bool status, string mess…...

ffmpeg给视频添加时间水印,准确且不模糊

ffmpeg -i {输入文件路径} -vf{drawtext} {输出文件路径} 针对视频模糊&#xff0c;加上 -b:v {输出视频码率}&#xff1b;右键属性&#xff0c;可查看离线视频源码率&#xff1b; 针对离线视频文件加上时间水印&#xff0c;时间跳变不正常&#xff0c;加上-re&#xff1b; 整…...

① vue复习。从安装到使用

vue官网&#xff1a;cn.vuejs.org vue安装 cnpm install -g vue/cli 查看是否安装成功 vue --version 创建一个项目 vue create vue-demo(项目名称) 这个取消掉。空格可选中或者取消。 运行项目&#xff1a; cd 进入到项目下 npm run serve 运行成功后&#xff0c;访问这…...

【Linux】多线程——线程引入 | 线程控制

文章目录 一、Linux多线程1. 线程概念2. 线程创建3. 线程和进程4. 线程的优缺点 二、线程控制1. 线程创建2. 线程终止3. 线程等待4. 线程分离5. 线程局部存储 三、线程封装 一、Linux多线程 一级页表和二级页表都是key/val模型&#xff0c;一级页表的key是第一份的10个比特位&a…...

查询树形目录(内存遍历成树返回)

实体 Data TableName("dtp_sm_servicetype") ApiModel(value "SmServicetype对象", description "服务类型") EqualsAndHashCode(callSuper true) public class SmServicetype extends BaseEntity {ApiModelProperty("服务类型名称&quo…...

Easys Excel的表格导入(读)导出(写)-----java

一,EasyExcel官网: 可以学习一些新知识: EasyExcel官方文档 - 基于Java的Excel处理工具 | Easy Excel 二,为什么要使用easyexcle excel的一些优点和缺点 java解析excel的框架有很多 &#xff1a; poi jxl,存在问题&#xff1a;非常的消耗内存&#xff0c; easyexcel 我们…...

纯净版ISO镜像下载大全(Windows、Linux、mac)

目录 一、前言介绍 前言必读 介绍 二、获取ISO镜像方式 &#xff08;一&#xff09;官方镜像下载 &#xff08;二&#xff09;获取下载方式 ps&#xff1a;回复的内容都是小写的 Windows操作系统 1.windows XP系统 2.Windows 7系统 3.Windows10系统 4.Windows11系…...

VMware上的Centos设置静态IP

服务器环境一般都是Centos7&#xff0c;而且很多软件在Linux环境上也能支持得更好&#xff0c;所以我需要在本机上使用虚拟机安装Linux&#xff0c;因为需要访问Linux上安装的软件&#xff0c;所以需要固定IP&#xff0c;不然每次更改也不方便。 基础环境准备 安装VMware在VM…...

【MySQL】数据库的基本操作

文章目录 1. 创建数据库1.1 创建数据库的语句1.2 创建一个数据库1.3 查看字符串与校验规则1.4 校验规则对数据库的影响 2. 删除数据库3. 查看数据库4. 修改数据库5. 备份与恢复5.1 数据库的备份与恢复5.2 表的备份与恢复 6. 查看数据库的连接情况 1. 创建数据库 1.1 创建数据库…...

Spring整合MyBatis(详细步骤)

Spring与Mybatis的整合&#xff0c;大体需要做两件事&#xff0c; 第一件事是:Spring要管理MyBatis中的SqlSessionFactory 第二件事是:Spring要管理Mapper接口的扫描 具体的步骤为: 步骤1:项目中导入整合需要的jar包 <dependency><!--Spring操作数据库需要该jar包…...

Linux:Shell编程之正则表达式

目录 绪论 1、正则表达式 1.1 通配符 1.2 正则表达式分类 1.3 基本正则 1.4 正则表达式中表示次数的表达式 1.5 位置锚定 1.5.1 词首锚定和词尾锚定 1.6 分组&#xff08;&#xff09; 1.7 逻辑或 1.8 扩展正则 绪论 正则表达式&#xff1a;有一类特殊字符以及文本…...

Python Opencv实践 - 图像缩放

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg_cat cv.imread("../SampleImages/cat.jpg", cv.IMREAD_COLOR) plt.imshow(img_cat[:,:,::-1])#图像绝对尺寸缩放 #cv.resize(src, dsize[, dst[, fx[, fy[, interpolation]]]]) #指定Size大…...

大脑营行|“福安市华龙教育基金”支持家乡教育事业发展

8月8日&#xff0c;福安市松罗中学举行“福安市华龙教育基金”中考奖学金颁发仪式。福安市松罗乡党委书记钟文、乡长郑仁寿、福安市人民政府教育督导室副科级督导员&#xff08;片区领导&#xff09;陈秦、校长张明亮、各村支部书记、家长代表、受奖学生&#xff0c;校领导班子…...

Windows 2016安装Jenkins

Jenkins 下载&#xff0c;安装 下载OpenJDK 11 for Wndows 两种方式 choco install openjdk11 https://github.com/adoptium/temurin11-binaries/releases/download/jdk-11.0.20%2B8/OpenJDK11U-jdk_x64_windows_hotspot_11.0.20_8.msi how to enable administrator user to …...

章节4:Burp Target模块

章节4&#xff1a;Burp Target模块 Burp渗透测试流程 01 Target模块的作用 与HTTP History的区别 HTTP History按时间顺序记录Target按主机或者域名分类记录&#xff08;字母顺序&#xff09; Target模块的作用 把握网站的整体情况对一次工作的域进行分析分析网站存在的攻…...

CAN总线一些经典的现场故障

本文分析一些经典的CAN总线现场故障。 1、CAN总线的常见故障 CAN总线错误分析与解决 当CAN总线出现故障或数据传输异常时,往往会出现多种奇怪的故障现象,如仪表板显示异常,车辆无法启动,启动后无法熄灭,车辆动力性能下降,某些电控系统功能失等。 这是因为相关数据或信息…...

VS+QT+Opencv使用YOLOv4对视频流进行目标检测

对单张图像的检测&#xff0c;请参考&#xff1a;https://blog.csdn.net/qq_45445740/article/details/109659938 #include <fstream> #include <sstream> #include <iostream> #include <opencv2/dnn.hpp> #include <opencv2/imgproc.hpp> #inc…...

oracle创建管理用户并授权

oracle创建管理用户并授权 创建用户 create user test identified by test;修改密码 alter user test identified by 123456;删除用户 drop user test;删除拥有对象的用户 若用户拥有对象&#xff0c;则不能直接删除&#xff0c;否则将返回一个错误值。指定关键字cascade,…...

​三江学院图书馆藏八一新书《乡村振兴战略下传统村落文化旅游设计》

​三江学院图书馆藏八一新书《乡村振兴战略下传统村落文化旅游设计》...

国防科技大学计算机基础课程笔记02信息编码

1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制&#xff0c;因此这个了16进制的数据既可以翻译成为这个机器码&#xff0c;也可以翻译成为这个国标码&#xff0c;所以这个时候很容易会出现这个歧义的情况&#xff1b; 因此&#xff0c;我们的这个国…...

51c自动驾驶~合集58

我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留&#xff0c;CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制&#xff08;CCA-Attention&#xff09;&#xff0c;…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

visual studio 2022更改主题为深色

visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中&#xff0c;选择 环境 -> 常规 &#xff0c;将其中的颜色主题改成深色 点击确定&#xff0c;更改完成...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)

【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...