字符串匹配:从机器到后缀自己主动KMP
后缀自己主动机(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的更多相关文章
- 快速字符串匹配一: 看毛片算法(KMP)
前言 由于需要做一个快速匹配敏感关键词的服务,为了提供一个高效,准确,低能耗的关键词匹配服务,我进行了漫长的探索.这里把过程记录成系列博客,供大家参考. 在一开始,接收到快速敏感词匹配时,我就想到了 ...
- 字符串匹配的KMP算法
~~~摘录 来源:阮一峰~~~ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串”BBC ABCDAB ABCDABCDABDE”,我想知道,里面是否包含另一个字符串”ABCDABD”? 许 ...
- 字符串匹配(hash算法)
hash函数对大家来说不陌生吧 ? 而这次我们就用hash函数来实现字符串匹配. 首先我们会想一下二进制数. 对于任意一个二进制数,我们将它化为10进制的数的方法如下(以二进制数1101101为例): ...
- 字符串匹配的KMP算法详解及C#实现
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
- 字符串匹配与KMP算法实现
>>字符串匹配问题 字符串匹配问题即在匹配串中寻找模式串是否出现, 首先想到的是使用暴力破解,也就是Brute Force(BF或蛮力搜索) 算法,将匹配串和模式串左对齐,然后从左向右一个 ...
- 字符串匹配--kmp算法原理整理
kmp算法原理:求出P0···Pi的最大相同前后缀长度k: 字符串匹配是计算机的基本任务之一.举例,字符串"BBC ABCDAB ABCDABCDABDE",里面是否包含另一个字符 ...
- 字符串匹配的KMP算法(转)
转载:http://kb.cnblogs.com/page/176818/ 字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE&quo ...
- 实现字符串匹配的KMP算法
KMP算法是Knuth-Morris-Pratt算法的简称,它主要用于解决在一个长字符串S中匹配一个较短字符串s. 首先我们从整体来把我这个算法的思想. 字符串匹配的朴素算法: 我们容易想到朴素算法, ...
- 字符串匹配之horspool算法(简化的BM算法)
前面介绍在BF,KMP这些算法的时候老是提到BM这个东西,究竟这什么东西,有啥高深的,这些问题我们如今不去考虑.不知道,认真读前几篇文章的读者有没有发现前面的算法都是从模式串的前面開始匹配的,那我们就 ...
随机推荐
- error C2220: warning treated as error - no 'object' file generated warning C4819: The file contains a character that cannot be represented in the current code page (936).
用Visual Studio2015 编译时,遇到如下编译错误: error C2220: warning treated as error - no 'object' file generated ...
- markdown + vim
https://www.jianshu.com/p/24aefcd4ca93https://github.com/isnowfy/python-vim-instant-markdownhttps:// ...
- swift学习第五天:字符串
字符串的介绍 字符串在任何的开发中使用都是非常频繁的 OC和Swift中字符串的区别 在OC中字符串类型时NSString,在Swift中字符串类型是String OC中字符串@"" ...
- Activity 调用Service的方法
一般来说,Activity调用Service 分为两种:进程内调用和进程间调用.进程内调用时比较常用的一种,在进程内调用中我们常常使用的是bindService来启动Service(关于这种启动方式的 ...
- windows 空闲超时 非管理员如何破解
windows 空闲超时 非管理员如何破解
- Android 升级到android studio 2.2项目死活run不起来
背景:升级到Android studio 2.2项目死活运行不起来 现象如下: run with --stacktrace --debug等等抛出的bug简直无法忍视 解决办法:把compileSdk ...
- Java8获取参数名及Idea/Eclipse/Maven配置
在Java8之前,代码编译为class文件后,方法参数的类型固定,但是方法名称会丢失,方法名称会变成arg0.arg1.....而现在,在Java8开始可以在class文件中保留参数名,这就给反射带来 ...
- Android XMPP服务器, BOSH(Http-Binding)和WEB客户端搭建
目标: 搭建一个XMPP服务器, 实现在web page上用javascript与自己XMPP服务器通信, 匿名登录并与任何一个XMPP(Jabber)帐户通信. (Gtalk目前尚有问题) XMPP ...
- FullPage.js全屏滚动插件解说
1.主要功能 1).支持鼠标滚动 2).多个回调函数 3).支持手机.平板触屏事件 4).支持css3动画 5).支持窗口缩放 6).窗口缩放时自动调整 7).可设置滚动宽度.背景颜色.滚动速度.循环 ...
- 【t082】牛跑步
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 新牛到部队,CG要求它们每天早上搞晨跑,从A农场跑到B农场.从A农场到B农场中有n-2个路口,分别标上 ...