字符串匹配:从机器到后缀自己主动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这个东西,究竟这什么东西,有啥高深的,这些问题我们如今不去考虑.不知道,认真读前几篇文章的读者有没有发现前面的算法都是从模式串的前面開始匹配的,那我们就 ...
随机推荐
- 《编程导论(Java)·4.1数据抽象的含义》
You have no choice about the necessity to integrateyour observations, your experiences, your knowled ...
- ios开发网络学习十二:NSURLSession实现文件上传
#import "ViewController.h" // ----WebKitFormBoundaryvMI3CAV0sGUtL8tr #define Kboundary @&q ...
- 关于LayoutParams 分类: H1_ANDROID 2013-10-27 20:34 776人阅读 评论(0) 收藏
每一个布局均有一个叫LayoutParams的内部类,如: LinearLayout.LayoutParams RelativeLayout.LayoutParams AbsoluteLayout ...
- jquery简单使用(看教程:快全有实例)(固定样式:$().val()设置属性,$().click()设置方法)
jquery简单使用(看教程:快全有实例)(固定样式:$().val()设置属性,$().click()设置方法) 一.总结 1.jquery不懂之处直接看教程,案例都有,有简单又快 2.jquery ...
- 解决win7系统不支持16位实模式汇编程序DOS执行的问题
这学期学习了汇编,在自己电脑上发现,win7的dos不支持16位实模式. 对编程来说,不能执行程序是致命的. 在经过网上搜集资料后,得到一种解决的方法--使用dosbox软件执行 dosbox简单说, ...
- git入门基础
git基础 参考: 官网git基础 git 文件的生命周期 文件的生命周期图: git中的文件可以分为4个阶段. Untracked : 这是目录中没有被跟踪的文件,即不在git项目中,使用 git ...
- 剔除list中相同的结构体数据
剔除list中相同的结构体数据,有三个思路:1.两层循环,逐个比较 2.使用set容器来剔除 3.使用unique方法去重 // deduplication.cpp : 定义控制台应用程序的入口点. ...
- MySQL经常使用的面试题
1.怎样登陆mysql数据库 MySQL -u username -p 2.怎样开启/关闭mysql服务 service mysql start/stop 3.查看mysql的状态 service m ...
- Android Snackbar使用方法及小技巧-design
Snackbar和Toast相似,都是为了给用户提供交互信息,Snackbar是固定在底部的,显示时从下往上滑出 要使用Snackbar,需要在项目的build.gradle中添加依赖 depende ...
- HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)
HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...