后缀自己主动机(sam)对字符串匹配

====

我们已经配置了一个相对较短的模式字符串sam。

为P="abcabcacab", T[1..i]后缀。因此,它是sam最长前缀长度:

T: b a b c b a b c a b c a a b c a b c a b c a c a b  c

   1 1 2 3 1 1 2 3 4 5 6 7 1 2 3 4 5 6 7 5 6 7 8 9 10 4

假设最长前缀长度是|P|,则表示T[1..i]的后缀和P匹配。

内存使用

可能多个trans指针同一个节点。因此像删除树那样会引起double-free:

为此我们临时採用内存池的做法。

假设扩展到包含数字和空格,则须要表示37个转移指针。

KMP算法

====

给定模式串P,文本串T,

如果在s位置已匹配了q个字符, 即P[1,..,q]=T[s+1,..,s+q], 而在P[q+1]不匹配。

strstr()这时会把指针指向s+2,从P[1]又一次開始匹配。

当时Knuth,Morris,Pratt就想可不能够把指针再移远一点。

如果有P[1,..,k]=T[s+q+1-k,..,s+q],这时从P[k+1]開始比即可了,显然我们希望k越大越好,相应地指针移动增量=q-k越小,因此应该不会错过某些全然匹配的位置。

我们把上面两个等式合并,得到P[1,..,k]是P[1,..,q]的后缀。

问题变成:

对于每一个q, 求P[1,..,q]的最长的真前缀(长度记为k),同一时候它也是P[1,..,q]的后缀。

我们定义前缀函数pi(q):=k.





怎样计算pi(q) ?

====

使用递推的想法,如果我们已经计算好了pi(q)=k。

假设P[k+1] = P[q+1], 则显然有pi(q+1) = k+1;

否则,看作是一个匹配问题, 我们来看pi(q)的含义是与P[1,..,q]末尾匹配的最长前缀长度k,我们就拿这个前缀来匹配,并期望P[k+1]和P[q+1]一样,否则k=pi(k)循环下去。

初始条件:pi(1) = 0, 由于最长真前缀是空串。





当前P[1,..,k]匹配T[q-k+1,q],而在T[q+1]不匹配。

应用前缀函数的定义。应该从位置s+1-k + q-k = 

一个字符串P[1,..,j]去匹配P[q+1-j,..q+1]的过程。

k=pi(k), 直到P[k] = P[q+1]。





怎样做线性的字符串匹配?

====

參照后缀自己主动机的做法, 我们把pi和P组成一个自己主动机,T在这个自己主动机上

走一遍。

前缀函数练习题目:

1. P 在T中的出现次数? 提示:检查pi(PT)

2. (ab)^3 = ababab, 怎样求最大的反复因子r=3?

3. 怎样在线性时间内推断是否为循环移位,比方arc和car。(这个我还不知道怎么做)

KMP比SAM节省内存:

版权声明:本文博客原创文章。博客,未经同意,不得转载。

字符串匹配:从机器到后缀自己主动KMP的更多相关文章

  1. 快速字符串匹配一: 看毛片算法(KMP)

    前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索.这里把过程记录成系列博客,供大家参考. 在一开始,接收到快速敏感词匹配时,我就想到了 ...

  2. 字符串匹配的KMP算法

    ~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...

  3. 字符串匹配(hash算法)

    hash函数对大家来说不陌生吧 ? 而这次我们就用hash函数来实现字符串匹配. 首先我们会想一下二进制数. 对于任意一个二进制数,我们将它化为10进制的数的方法如下(以二进制数1101101为例): ...

  4. 字符串匹配的KMP算法详解及C#实现

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  5. 字符串匹配与KMP算法实现

    >>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个 ...

  6. 字符串匹配--kmp算法原理整理

    kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...

  7. 字符串匹配的KMP算法(转)

    转载:http://kb.cnblogs.com/page/176818/ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE&quo ...

  8. 实现字符串匹配的KMP算法

    KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...

  9. 字符串匹配之horspool算法(简化的BM算法)

    前面介绍在BF,KMP这些算法的时候老是提到BM这个东西,究竟这什么东西,有啥高深的,这些问题我们如今不去考虑.不知道,认真读前几篇文章的读者有没有发现前面的算法都是从模式串的前面開始匹配的,那我们就 ...

随机推荐

  1. Nginx+Tomcat搭建高性能负载均衡集群的实现方法

    一.    目标实现高性能负载均衡的Tomcat集群: 二.步骤 1.首先下载Nginx,要下载稳定版: 2.然后解压两个Tomcat,分别命名为apache-tomcat-6.0.33-1和apac ...

  2. [Yarn] Use Yarn to Create an Alternative Import Name of an Installed Library

    In this lesson we'll show how to use yarn to alias the names of same npm libraries but install diffe ...

  3. [Angular2 Router] Resolving route data in Angular 2

    From Article: RESOLVING ROUTE DATA IN ANGULAR 2 Github If you know Anuglar UI router, you must know ...

  4. 用strace排查故障的5种简单方法(每日一译)

    原文链接:5 simple ways to troubleshoot using Strace 我很意外大部分人都不知道如何使用strace.strace一直是我的首选debug工具,因为它非常的有效 ...

  5. Boost.Asio c++ 网络编程翻译(10)

    read/write方法 这些方法对一个流进行读写操作(能够是套接字,或者其它表现的像流的类): async_read(stream, buffer [, completion],handler):这 ...

  6. 《iOS Human Interface Guidelines》——Edit Menu

    编辑菜单 用户能够显示一个编辑菜单来在文本视图.网页视图和图像视图运行诸如剪切.粘贴和选择的操作. 你能够调整一些菜单的行为来在你的app中给用户给多的内容控制.比方你能够: 指定哪一个标准菜单命令对 ...

  7. [Docker] Create a Volume

    We can create volumn to keep the data, even we stop the container and restart again, the data won't ...

  8. DisplayPageBoundaries 打开word后自动将页面间空白隐藏 (auto+定时器)

    每次打开文档都要鼠标点击页面间空白处,将其隐藏 尝试过在 AutoOpen, AutoExec等宏中添加 ActiveWindow.View.DisplayPageBoundaries = False ...

  9. erlang---启动参数学习/研究

    erlang启动参数有3种:emulator flags, flags 和plain arguments. emulator flags 是以“+”开头的,用来控制模拟器的行为,附送一个非常实用的例子 ...

  10. sparksql dataset

    java /** *2.0之后使用sparksession即可,不需要再去创建sqlcontext *@author Tele * */ public class Demo { private sta ...