1. 单模式串匹配
    BF 算法和 RK 算法
    BM 算法和 KMP 算法
  2. 多模式串匹配算法
    Trie 树和 AC 自动机

一、 什么是“Trie树”?

1. 他是一种树形结构,是一种专门处理字符串匹配的数据结构,解决在一组字符串集合中快速查找某个字符串的问题。

2. Trie树的本质是利用字符串之间公共前缀,将重复的前缀合并在一起

Trie 树的本质,就是利用字符串之间的公共前缀,将重复的前缀合并在一起。

how,hi,her,hello,so,see

其中,根节点不包含任何信息,每个节点表示一个字符串中的字符,从根节点到红色节点的一条路径表示一个字符串(红色节点并不都是叶子节点)。

3. 查找

当在Trie树中查找一个字符串时,如“her”,就将要查找的字符串分割成单个的字符h,e,r,然后从Trie树的根节点开始匹配。但,假若要查找的字符串是“he”,用上面同样的方法,从根节点开始,沿着某条路径来匹配,发现路径的最后一个节点“e”不是红色的,即“he”是某个字符串的前缀,但不能完全匹配任何字符串。

二 、如何实现一课Trie树?

1,Trie树主要有两个操作,一个是将字符串集合构造成Trie树。这个程可分解为:

  • 将一个字符串插入到Trie树的过程
  • 在Trie树中查询一个字符串

2,如何存储一个Trie树

①:Trie树是一个多叉树,需要存储一个节点的所有子节点的指针。
②:一种经典的存储方式:借助散列表额思想,通过一个下标与字符一一映射的数组,来存储子节点的指针。

class TrieNode {char data;TrieNode children[26];
}

借助散列表的思想,我们通过一个下标与字符一一映射的数组,来存储子节点的指针。

假设字符串中只有从a到z这26个小写字母,从数组中下标为0的位置,存储指向子节点a的指针,下标为1的位置存储指向子节点b的指针,以此类推,下标为25的位置,储存的是指向的子节点z的指针。如果某个字符的子节点不存在,就在对应的下标的位置存储null。
当在Trie树中查找字符串的时候,就可以通过字符的ASCII码减去“a”的ASCII码,迅速找到匹配的子节点的指针。


public class Trie {private TrieNode root = new TrieNode('/'); // 存储无意义字符// 往Trie树中插入一个字符串public void insert(char[] text) {TrieNode p = root;for (int i = 0; i < text.length; ++i) {int index = text[i] - 'a';if (p.children[index] == null) {TrieNode newNode = new TrieNode(text[i]);p.children[index] = newNode;}p = p.children[index];}p.isEndingChar = true;}// 在Trie树中查找一个字符串public boolean find(char[] pattern) {TrieNode p = root;for (int i = 0; i < pattern.length; ++i) {int index = pattern[i] - 'a';if (p.children[index] == null) {return false; // 不存在pattern}p = p.children[index];}if (p.isEndingChar == false) return false; // 不能完全匹配,只是前缀else return true; // 找到pattern}public class TrieNode {public char data;public TrieNode[] children = new TrieNode[26];public boolean isEndingChar = false;public TrieNode(char data) {this.data = data;}}
}

3,时间复杂度:

构建 Trie 树 时间复杂度 O(n)(n 表示所有字符串的长度和)
在 Trie 树中,查找某个字符串的时间复杂度 O(k),k 表示要查找的字符串的长度
在一组字符串中,频繁的查询某些字符串,用Trie树非常高效。

4,Trie树很耗内存吗?

Trie树是使用数组来储存一个节点的子节点的指针的,即便一节点只有很少的子节点,远小于26个,比如2,3个,也要维护一个长度为26的数组。
Trie的本质是避免重复存储一组字符串的相同前缀子串,但现在每个字符(对应一个节点)的存储远远大于1个字节。
如果字符串中不仅包含小写字母,还包含大写字母,数字,甚至是中文,那需要的存储空间就更多了。所以在重复前缀并不多的情况下,Trie树不但不节省内存,还有可能浪费更多的内存。

5,Tri树的优化方案:
  • 牺牲一点查询的效率,将每个节点中的数组换成其他数据结构,来存储一个节点指针。如:有序数组,跳表,散列表,红黑树等。
    假设用有序数组,数组中的指针按照指向的子节点中的字符大小顺序排序。查询时,可以通过二分查找的方法,快速查找到某个字符应该匹配的子节点的指针。

  • 缩点优化,就是对只有一个子节点的节点,而且此节点不是一个串的结束节点,可以将此子节点合并。这样可以节省空间,但却增加了编码难度。

三 、Trie数与散列表的,红黑树的比较(应用与局限 )

1,字符串的匹配问题,笼统上讲,其实就是数据的查找问题。

2,在一组字符串中查找字符串,Trie数实际上表现的并不好,他对要处理的字符串有极其严苛的要求:

  • 第一,字符中包含的字符集不能太大,如果字符集太大,那么存储空间就可能浪费很多。即便优化也要付出牺牲查询,插入效率的代价。
  • 第二,要求字符串的前缀重合比较到,不然空间消耗会变大很多。
  • 第三,如果要用Trie树解决问题,就需要自己从零开始实现一个Trie树,还要保证没有bug,这在工程上是把简单问题复杂化。
  • 第四,通过指针串起来的数据是不连续的,而Trie树用到了指针,所以,对缓存并不友好。性能上会打个折扣。

综上:Trie树不适合精确匹配查找,这种问题更适合用散列表或红黑树来解决。Trie树比较适合的是查找前缀匹配的字符串。Trie的这个特点可以扩展到更加广泛的一个应用上:自动输入补全。比如输入法自动补全功能、IDE 代码编辑器自动补全功能、浏览器网址输入的自动补全功能等等。

笔记整理来源: 王争 数据结构与算法之美

【数据结构与算法】【字符串匹配】Trie树相关推荐

  1. 数据结构与算法 / 字符串匹配 / Trie 树

    一.诞生原因 传统字符串比较时,需要将待比较的字符串与字符串集合中每一个串进行比较,结果比较浪费时间. Trie 树的发明就是为了解决上述问题. 二.基本信息 又称字典树,是一种树形结构,是一种哈希树 ...

  2. 数据结构与算法 / 字符串匹配 / BF、PK 算法

    零.前言 为了下面便于说明,先定义两个名词,分别是主串和模式串.在字符串 A 中查找字符串 B,则 A 为主串,B 为模式串. 假设,主串中字符数量为 L1,模式串的字符数量为 L2 . 一.BF 算 ...

  3. 头歌-数据结构与算法-字符串匹配

    第1关:实现朴素的字符串匹配 #include <stdio.h> #include <stdlib.h> #include "mystr.h" #prag ...

  4. 数据结构-----基于双数组的Trie树

    Trie树简介 Trie树也称字典树,在字符串的查找中优势比较明显,适用于在海量数据中查找某个数据.因为Trie树的查找时间和数据总量没有关系,只和要查找的数据长度有关.比如搜索引擎中热度词语的统计. ...

  5. 算法学习之Trie树

    算法学习之Trie树 by MPS [定义]   trie树又名字母树,是针对字符串的匹配,查找的一种高效手段,是哈希表的一种变种,但青出于蓝胜于蓝.我这个蒟蒻也是表示啃了两天才啃出来这些皮毛,当做学 ...

  6. 数据结构与算法(C++)– 树(Tree)

    数据结构与算法(C++)– 树(Tree) 1.树的基础知识 树(tree): 一些节点的集合,可以为空集 子树(sub tree): 树的子集 根(root): 树的第一个节点 孩子和父亲(Chil ...

  7. C++KMP算法字符串匹配(附完整源码)

    C++KMP算法字符串匹配 C++KMP算法字符串匹配完整源码(定义,实现,main函数测试) C++KMP算法字符串匹配完整源码(定义,实现,main函数测试) #include <iostr ...

  8. 数据结构与算法(C#实现)系列---树

    Heavenkiller(原创) 首先我们给树下一个定义: 树是一个有限的.非空的结点集, T={r} or T1 or T2 or-or Tn 它具有下列性质: 1.集合指定的结点r叫做树的根结点 ...

  9. kmp算法字符串匹配C语言实现

    kmp算法字符串匹配 在leetcode做题时,有道题就是写一个strstr函数,先用思路最简单的直接两个循环做,提示时间超过限制.就查了查kmp的资料 翻了下算法导论,感觉像在看数学书,看不太懂,最 ...

  10. 11_JavaScript数据结构与算法(十一)树

    JavaScript 数据结构与算法(十一)树 树结构 什么是树? 真实的树: 树的特点: 树一般都有一个根,连接着根的是树干: 树干会发生分叉,形成许多树枝,树枝会继续分化成更小的树枝: 树枝的最后 ...

最新文章

  1. 【206】Firefox 扩展收集
  2. .NET开发必备网址
  3. 常用电脑密码破解技巧
  4. 论软件的模块化与架构
  5. linux平台关于内存,cpu,连接数,流量监控(一)
  6. adb zip linux 安装教程,centos下安装adb环境
  7. error 系统错误 错误码10007_工业界纠错系统
  8. 哈理工OJ—1598【DP最长公共子序列O(nlogn)】
  9. cad上样条曲线上的点太多了_CAD中如何编辑样条曲线增加夹点? 看完你就知道了...
  10. 一个在线QQ客服代码分析
  11. Android判断世界各国手机号码合法性
  12. HTML5小游戏源码收藏
  13. 2022年上半年软考报名常见问题及解答
  14. ROS多设备组网(WSL+miniPC+Nv Orin)
  15. html制作多媒体课件,多媒体课件设计与制作 教师课件制作平台
  16. kindle电子书资源搜索及制作教程
  17. in语句作用C语言,C语言中IN(ch,OP)是什么意思
  18. POJ 1950 Dessert
  19. 【Unity3d】3d网页游戏场景打包与加载
  20. php连接mysql 500错误日志_php javascript从mysql获取数据会在服务器端产生500错误

热门文章

  1. android深度探索 HAL及驱动开发 第八章
  2. json字符串生成C#实体类的工具
  3. 用excel打开文本内容
  4. InnoDB的auto_increment指定值被重置问题
  5. linux普通用户发送信号,Linux信号发送与作业控制
  6. 坡度土方计算案例_土石方工程造价中的细节解析(案例+计算式)
  7. SQL语句:建表语句、插入语句、查询语句、增加列、删除列、查询语句like、修改语句
  8. 宝塔面板 创建 二级域名 Unable to round-trip http request to upstream
  9. php去除英文和标点,php 过滤英文标点符号及过滤中文标点符号代码_php技巧
  10. js IE和Firefox下event处理