后缀自己主动机(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. boost::asio的http client应用笔记

    1 踩过的坑 1.1 io_service boost::asio::io_service::run()会一直运行到没有任务为止,假设中途调用stop().则全部等待中的任务会立马运行.要在停止的时候 ...

  2. 在vue中使用babel-polyfill

    在 Vue.js项目中使用Vuex,Vuex 依赖 Promise,所以如果你的浏览器没有实现 Promise (比如 IE),那么就需要使用一个 polyfill 的库 我们可以通过babel-pr ...

  3. java连接MongoDB查询导出为excel表格

    背景 因为项目需求.每一个星期须要统计每一个公众号7天的訪问数,月底就须要统计一个月的訪问数,40多个公众号.每次手动统计都须要花费1个小时,总之是一项无技术耗时耗神的手工活. 于是.想写个程序来统计 ...

  4. php 过滤js字符串代码

    $str = '<script type="text/javascript" src="dd.js"></script> 测试php正则 ...

  5. input常用输入框限制

    input常用输入框限制 本篇 1.小写自动转换成大写:  or 2.大写自动转换成小写  or 3.防止退后清空的TEXT文档 4.ENTER键可以让光标移到下一个输入框 5.只能为中文(有闪动) ...

  6. BootStrap让两个控件在一行显示

    <div class="row"> <div> <label class="form-inline">参加单位:<in ...

  7. Linux中LVM2原理及制作LVM2

    Linux中LVM2原理及制作LVM2 一.LVM原理 [MD]:Multi Device 多设备 Mdadm是一个用户空间工具,是RAID的管理工具,与真正的RAID工作没有太大关系.真正的RAID ...

  8. jquery平滑滚动页面

    滚动到顶部 $('.scroll_top').click(function(){$('html,body').animate({scrollTop: '0px'}, 800);}); 滚动到指定位置 ...

  9. 【u031】租用游艇

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 长江游艇俱乐部在长江上设置了n 个游艇出租站1,2,-,n.游客可在这些游艇出租站租用游艇,并在下游的 ...

  10. 【codeforces 604D】Moodular Arithmetic

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...