首页 > 其他分享 >2025dsfz集训Day7: KMP与Trie树

2025dsfz集训Day7: KMP与Trie树

时间:2025-01-19 11:22:00浏览次数:1  
标签:我们 匹配 Trie Day7 对应 2025dsfz 字符串 border 最长

Day7: KMP与Trie树

KMP算法

  • \(KMP (Knuth–Morris–Pratt)\) 是一个字符串匹配算法,于1977年由上述三人共同发表。
    在线性的时空复杂度内解决字符串匹配。

字符串匹配

  • 给定两个字符串 \(s,t\)(通常来讲我们管较短的串叫做“模式串”,长的叫“匹配串”。我们的任务是在长串内找到短串)。

  • 我们定义记号 \(s[l,r]\) 表示的是 \(s\) 串,从下标 \(l\) 到下标 \(r\) 的子串。(比如说 \(s=“abcabca”\),那么 \(s[2,4]=“bca”,1-index\))

  • 字符串匹配:我们希望对于 s(长串)的每一个前缀 s[1,i],找到最大的 j 使得 s[i-j+1,i]=t[1,j]

  • 例:\(s=“ababc”,t=“aba”:\)
    \(i=1: s[1,1]=t[1,1]=“a” ; i=2:\) \(s[1,2]=t[1,2]=“ab”\)
    \(i=3: s[1,3]=t[1,3]=“abc”\)(成功匹配); \(i=4: s[3,4]=t[1,2]=“ab”\)
    \(i=5: s[6,5]=t[1,0]=\phi\)  (未成功匹配,空串)

解法

  • 我们希望能够复用尽量多的信息。
  • 假设我们此时知道 \(s[1,i]\) 对应的匹配长度 \(k_i\),怎么求出 \(s[1,i+1]\) 的匹配长度?
  • 大致思路:先看看 \(s[i+1]\) 和 \(t[k_i+1]\) 一不一样。
    • 一样:长度++
    • 不一样:模式串前移 \(1\) 位

Border串

  • 我们注意到,实际上我们是在找 \(t[1,j]\) 的一个既是其前缀又是其后缀的最长的子串。(当然需要不是 \(t[1,j]\) 本身)

  • \(s=“abab”\) 那么 \(s[1,2]=“ab”\) 就是这样的串。
    即是前缀又是后缀串的名字是:\(border\) 串。

  • 我们可以发现 \(border\) 集合:\(S_i=S_k+{k}\) ( \(k\) 是 \(t[1,i]\) 的最长border)。

    • 例:\(BS(“ababa”)={“a”,“aba”}=BS(“aba”)+{“aba”}\)
      其中 \(BS\) 是 \(border\ set\) 的意思(即所有的 \(border\) 串构成的集合)
  • 这实际上也就是说:\(border\) 集合实际上是一条链

  • 我们不断地去找串 \(S\) 的最长 \(border T\),然后把他加入集合,把 \(S\) 变成 \(T\) 直到 \(S\) 为空。

  • 现在问题变为:如何求出最长 \(border\)?

  • 假设我们知道了 \(s[1,i]\) 的 \(border\),怎么求出 \(s[1,i+1]\) 的 \(border\) 长度?
    我们不断地“跳” \(t[1,i]\) 的 \(border\) 来找到 \(t[1,i+1]\) 的 最长 \(border\)。

复杂度

  • 看起来是 \(O(n^2)\) 的,但实则不然。

  • 考虑每次最多让 \(border\) 链 变长 \(1\) ,以 \(border\) 链 长度作为“势能”,便可以分析出 \(O(n)\) 的摊还复杂度。

  • 另一边的字符串匹配亦是同理。(算法,复杂度分析)

  • 假设 \(s[i-j+1,i]\) 匹配到了 \(t[1,j]\)。

    • 我们不断地去 “跳” \(t[1,j]\) 的 \(border\),找到一个 \(t[1,k]\) 使得 \(t[k+1]=s[i+1]\)。
    • 这样就完成了一次字符串匹配。
  • 我们不难分析出,字符串匹配的复杂度为:\(O(n+m)=O(|S|+|T|)\)

  • 不难发现,实际上 border 集合的结构,可以用一颗树来描述。

  • 以 S=“abababa” 举例。

    • \(S[1,1]\) 对应最长 \(border=\phi;\)
    • \(S[1,2]\) 对应最长 \(border=\phi 。\)
    • \(S[1,3]\) 对应最长 \(border=“a”;\)
    • \(S[1,4]\) 对应最长 \(border=“ab”。\)
    • \(S[1,5]\) 对应最长 $border=“aba”; $
    • \(S[1,6]\) 对应最长 \(border=“abab”。\)
    • \(S[1,7]\) 对应最长 \(border=“ababa”。\)
  • 如图,这棵树具有很优良的性质。

  • 可以发现,我们求解border的算法实际上不过是在 这棵树上进行 dfs。
    (图片已崩,请前往博客园查看)

Trie树

  • 我们有这样一个“数据结构”能够去“维护”给定的“串集合” \(S\)。并且能支持“查询”一个串在不在这个“串集合” \(S\) 中。(¥S$ 即为字典)
  • 很好理解,如图所示:假设字典 \(S={“she”,“he”,“shy”,“sheep”,“sheet”}\)
    • 那么字典树将如图所示:(图片已崩,请前往博客园查看)
    • 每一条边对应一个字母,每一个结点对应一个单词的前缀。
    • \(0\) 结点的含义是空串。
  • 查询就是从 \(0\) 开始查找有没有对应字母的出边。

01Trie树

  • \(0-1\)字典树可以很方便的维护形如“最大异或值”这类位运算查询。
  • 我们将一个 \(32/64\) 位整数看成一个长为 \(32/64\) 的字符串。
  • 例: \(4=(0…0100), 6=(0…0110), 11=(0…01011)\),将他们插入 \(trie\) 中:
    • 特点:所有叶子等深。
  • 假如我们想查询 \(x\) 与集合里的数最大异或值。
  • 比如说 $x=8=(1000) $,我们从高往低按位考虑。
    • 在 \(root\) 处的出边是 \(1\),我们看 \(root\) 有无 \(0\) 的出边,
    • 然后走向“结点 \(0\)”。(这样才能让异或值最大)
    • 接下来同理,我们在“结点 \(0\)” 看有没有 \(1\) 的出边……
      (图片已崩,请前往博客园查看)

标签:我们,匹配,Trie,Day7,对应,2025dsfz,字符串,border,最长
From: https://www.cnblogs.com/FrankWKD/p/18679412

相关文章

  • 2025dsfz集训Day3:DFS搜索与剪枝
    DAY3:DFS搜索与剪枝深搜深度优先搜索(DFS)是一种遍历或搜索树或图的算法,它从一个根节点开始,尽可能深地搜索每个分支,直到找到解为止。在搜索讨程中,为了提高效率,减少不必要的搜索,通常会采用各种剪枝优化策略。剪枝基本思想在深度优先搜索中,我们通常会遍历图或树的所有节点和边......
  • 2025dsfz集训Day5:最短路与最小生成树
    DAY5I:最小生成树生成树及最小生成树生成树是从一张无向连通图中选取一些边构成一张新图,使得这张图是是一棵树最小生成树即是让上述的生成树的边权和最小同时,最小生成树也会有一些性质在最小生成树上,两个点路径上经过的边权最小值即是这个点在原图中所有路径中可能经过......
  • 2025dsfz集训Day4:BFS及其优化
    DAY4:BFS及其优化BFS广度优先搜索(Breadth-First-Search)是一种图形数据结构的遍历算法。它从给定的起始顶点开始,首先访问起始顶点的所有邻接顶点,然后再依次访问这些邻接顶点的邻接顶点,以此类推,一层一层地向外扩展,直到遍历完整个图或者找到目标顶点。\(BFS\)的空间优化:使......
  • 2025dsfz集训Day6: 数论
    DAY6:数论快速幂快速幂是针对快速求解\(A^b\)结果的算法,对于\(b\)可以分解为2进制,例如对\(3^{11}=3^{2^3+2^1+2^0}\),由于\(b\)可以被分解后最多只会包含\(log_2b\)个1,因此时间复杂度为\(O(log_2b)\),而并非原本的\(O(b)\)例题洛谷P1226|【模板】快速幂这题要记得每......
  • 科普文:算法和数据结构系列【高效的字符串检索结构:字典树Trie树原理、应用及其java示例
    概叙科普文:算法和数据结构系列【算法和数据结构概叙】-CSDN博客科普文:算法和数据结构系列【非线性数据结构:树Tree和堆Heap的原理、应用、以及java实现】-CSDN博客科普文:算法和数据结构系列【树:4叉树、N叉树】_动态维护四叉树-CSDN博客科普文:算法和数据结构系列【二叉树总结......
  • 【LeetCode】力扣刷题热题100道(31-35题)附源码 搜索二维矩阵 岛屿数量 腐烂的橙子 课程
    一、搜索二维矩阵编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:每行的元素从左到右升序排列。每列的元素从上到下升序排列。可以使用从右上角开始搜索的方法来有效地找到目标值。选择起始位置:从矩阵的右上角开始。......
  • THREE.js学习笔记6——Geometries
    这一小节学习THREE.js中的物理模型。什么是geometry?(英文解释,翻译为中文就看不懂了,直接看英语吧)Composedofvertices(pointcoordinatesin3Dspaces)andfaces(trianglesthatjointhoseverticestocreateasurface)Canbeusedformeshesbutalsoforparticles......
  • {LOJ #6041. 「雅礼集训 2017 Day7」事情的相似度 题解
    \(\text{LOJ\#6041.「雅礼集训2017Day7」事情的相似度题解}\)解法一由parent树的性质得到,前缀\(s_i,s_j\)的最长公共后缀实质上就是\(i,j\)在SAM中的\(\operatorname{LCA}\)在SAM中的\(\operatorname{len}\)。让我们考虑如何处理\((l,r)\)区间内的询问。直......
  • 利用WikipediaRetriever集成Wikipedia内容到AI应用
    在当今信息爆炸的时代,如何高效地获取和利用海量的知识资源成为一个备受关注的问题。Wikipedia是全球最大、最受欢迎的百科全书资源之一,它由来自世界各地的志愿者共同维护和更新。WikipediaRetriever为开发者提供了一种简单而高效的方式,将Wikipedia的内容集成到各类AI应用中,......
  • [数据结构学习笔记11] 前序树(Trie/Prefix tree)
    前序树(Trie/Prefixtree),它的一个典型的应用场景在搜索引擎里,当你输入查询关键字的时候,会联想自动补齐你想要输入的内容。比如,你输入app,下面可能会出来联想Apple,Applied等等。什么是Trie?Trie(读作Try)是这样一个数据结构,它把短语或者单词分解字母,然后以一种方式去存储,让添加、删......