浅析KMP算法
浅析KMP算法
KMP算法是一种线性字符串的匹配算法,将主串S与模式串T匹配。
首先朴素算法大家都会,就是直接从S的每一个位置开始,枚举比较,时间效率为O(nm),现在要想到一种化简的方式,使得时间复杂度得以减少,不考虑其他古怪的时间复杂度,那么必然要求是线性的。
观察串S=“aaaaab”,T=“aaab”,现在进行朴素的算法,看看有什么可化简的地方。
观察S匹配到第3位,T匹配到第3位的时候,发现下一位不能再匹配,此时说明S[1..3]=T[1..3],所以S[2..3]=T[2..3],有因为T[1..2]=T[2..3],所以S[2..3]=T[1..2],所以直接将T的第3位与S的第4位继续匹配。
以此类推……
归纳上述过程,就是通过模式串T本身的性质跳过某些与主串S匹配回合。令S[i]表示S的长度为i的前缀,next[i]为S[i]的前缀与S[i]的后缀的最长公共前缀的长度,某次匹配失败时,若模式串匹配至第j个字符,则可将模式串向右移next[i]位(next[i]个字符完全相同),若再不行,再移。当j=length(T)时,匹配成功,这种算法的复杂度被证明是O(n+m)
下面贴个代码:
//这个代码用来求有多少个位置满足匹配且分别是什么位置
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
const int L=200;
char s[L],t[L];
int ls,lt,next[L],p[L];
int main(void)
{
scanf("%s%s",s,t);
ls=strlen(s);
lt=strlen(t);
next[0]=-1;
intj=-1;
for(int i=1;i<lt;i++)
{
while(j!=-1&&t[i]!=t[j+1]) j=next[j];
j+=t[i]==t[j+1];
next[i]=j;
}
j=-1;
for(int i=0;i<ls;i++)
{
while(j!=-1&&s[i]!=t[j+1]) j=next[j];
j+=s[i]==t[j+1];
if(j==lt-1)
{
p[++p[0]]=i-lt+1;
j=next[j];
}
}
for(int i=0;i<=p[0];i++) printf("%d\n",p[i]);
return 0;
}
小结本章内容,主要掌握KMP算法以及其算法思想。
浅析KMP算法的更多相关文章
- KMP算法浅析
具体参见: KMP算法详解 背景: KMP算法之所以叫做KMP算法是因为这个算法是由三个人共同提出来的,就取三个人名字的首字母作为该算法的名字.其实KMP算法与BF算法的区别就在于KMP算法巧妙的消除 ...
- 简单有效的kmp算法
以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...
- KMP算法
KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- KMP算法实现
链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...
- 数据结构与算法JavaScript (五) 串(经典KMP算法)
KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...
- 扩展KMP算法
一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...
- 字符串模式匹配之KMP算法图解与 next 数组原理和实现方案
之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 ...
- 算法:KMP算法
算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...
随机推荐
- MUI 微信 和支付宝支付 (前台代码)
<!-- 校园公告详情界面 用于显示校园公告的详情信息 在校园公告界面点击某一条目后 进入本界面查看详情 --> <!DOCTYPE html> <html> &l ...
- winform 配置文件的加密解密
winform 配置文件的加密解密Visual Studio 命令提示(2010) 窗口下直接输入 :解密aspnet_regiis -pdf connectionStrings 程序文件夹全目录 加 ...
- assert函数
这个函数在<cassert>里面,通常用来调试程序. eg: int i=1: assert(i==1):/什么也不做 assert(i==2)://程序会异常退出
- 在HTML5规范中div中读取预存的data-[key]值
HTML 代码: <div id="div_test" data-test="this is test" ></div> jQuery ...
- Cheatsheet: 2013 11.01 ~ 11.11
Other Back To Basics: Hashtables – Part2 How To Make A Game Part 1:Picking a Framework Modern Garbag ...
- 移除virbr0
在我们使用虚拟机管理器的图形界面来安装虚拟机的时候,自动创建虚拟网桥和虚拟网卡.另外,我们很少会在一个虚拟机中再安装一个虚拟机,所以,我们可以将宿主机上的网桥删除.方法如下: # virsh net- ...
- 在服务器端如何提取checkbox提交的数据?
HttpServeletRequest 单个字符串,getParameters() 多个字符串,getParametersValues(),返回一个数组,需要提前定义一个数组
- C#强制清除缓存
#region 强制清除缓存 [DllImport("kernel32.dll", EntryPoint = "SetProcessWorkingSetSize" ...
- Moq的使用
参考资料: 1. http://www.codeproject.com/Tips/729646/TDD-using-MOQ 2. https://github.com/Moq/moq4/wiki/Qu ...
- GitHub上不错的Android开源项目(三)
收集相关系列资料,自己用作参考,练习和实践.小伙伴们,总有一天,你也能写出 Niubility 的 Android App :-) GitHub上不错的Android开源项目(一):http://ww ...