浅析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算法的更多相关文章

  1. KMP算法浅析

    具体参见: KMP算法详解 背景: KMP算法之所以叫做KMP算法是因为这个算法是由三个人共同提出来的,就取三个人名字的首字母作为该算法的名字.其实KMP算法与BF算法的区别就在于KMP算法巧妙的消除 ...

  2. 简单有效的kmp算法

    以前看过kmp算法,当时接触后总感觉好深奥啊,抱着数据结构的数啃了一中午,最终才大致看懂,后来提起kmp也只剩下“奥,它是做模式匹配的”这点干货.最近有空,翻出来算法导论看看,原来就是这么简单(先不说 ...

  3. KMP算法

    KMP算法是字符串模式匹配当中最经典的算法,原来大二学数据结构的有讲,但是当时只是记住了原理,但不知道代码实现,今天终于是完成了KMP的代码实现.原理KMP的原理其实很简单,给定一个字符串和一个模式串 ...

  4. 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)

    前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...

  5. KMP算法实现

    链接:http://blog.csdn.net/joylnwang/article/details/6778316 KMP算法是一种很经典的字符串匹配算法,链接中的讲解已经是很明确得了,自己按照其讲解 ...

  6. 数据结构与算法JavaScript (五) 串(经典KMP算法)

    KMP算法和BM算法 KMP是前缀匹配和BM后缀匹配的经典算法,看得出来前缀匹配和后缀匹配的区别就仅仅在于比较的顺序不同 前缀匹配是指:模式串和母串的比较从左到右,模式串的移动也是从 左到右 后缀匹配 ...

  7. 扩展KMP算法

    一 问题定义 给定母串S和子串T,定义n为母串S的长度,m为子串T的长度,suffix[i]为第i个字符开始的母串S的后缀子串,extend[i]为suffix[i]与字串T的最长公共前缀长度.求出所 ...

  8. 字符串模式匹配之KMP算法图解与 next 数组原理和实现方案

    之前说到,朴素的匹配,每趟比较,都要回溯主串的指针,费事.则 KMP 就是对朴素匹配的一种改进.正好复习一下. KMP 算法其改进思想在于: 每当一趟匹配过程中出现字符比较不相等时,不需要回溯主串的 ...

  9. 算法:KMP算法

    算法:KMP排序 算法分析 KMP算法是一种快速的模式匹配算法.KMP是三位大师:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,所以取首字母组成KMP. 少部分图片来自孤~影 ...

随机推荐

  1. 【Java】JDBC连接MySQL

    JDBC连接MySQL 虽然在项目中通常用ORM的框架实现持久化.但经常因测试某些技术的需要,要写一个完整的JDBC查询数据库.写一个在这儿备份. 首先引入驱动包: <dependencies& ...

  2. UVA10339 Watching Watches

    题目大意:有两个表,每天都会慢一点时间,给出每天慢得秒数,问下一次重合的时刻. 解题思路:时刻重合也就是说整整差了一周,一周是12小时,用12小时的秒数除以两个表的相差那就是需要多少天的时间后重合,知 ...

  3. SUSE Linux Enterprise Server 设置IP地址、网关、DNS

    说明: ip:192.168.21.172 子网掩码:255.255.255.0 网关:192.168.21.2 dns:8.8.8.8 8.8.4.4 1.设置ip地址 vi /etc/syscon ...

  4. 【leetcode❤python】206. Reverse Linked List

    # Definition for singly-linked list.# class ListNode(object):#     def __init__(self, x):#         s ...

  5. C#正则表达式获取组名,按照组名输出匹配内容

    最近写了个正则表达式匹配的工具,可以按照组名输出匹配内容,还是挺方便的,代码留存一下,以后用的话,直接copy了. Regex regex = new Regex(this.textBoxRegex. ...

  6. V-rep学习笔记:机器人逆运动学数值解法(Damped Least Squares / Levenberg-Marquardt Method)

    The damped least squares method is also called the Levenberg-Marquardt method. Levenberg-Marquardt算法 ...

  7. Perform Cut Copy Paste Operations Using Cut_Region Copy_Region Paste_Region Commands In Oracle Forms

    You can do Select, Cut, Copy and Paste operations on text items in Oracle Forms using Select_All, Cu ...

  8. Oracle重置过期的密码

    过期的原因一般有两种可能: 一.由于Oracle 11g在默认的default概要文件中设置了“PASSWORD_LIFE_TIME=180”天导致:   这种情况的解决办法: 1.查看用户的proi ...

  9. python 中类方法@classmethod

    classmethod是用来指定一个类的方法为类方法,没有此参数指定的类的方法为实例方法,使用方法如下: class C: @classmethod def f(cls, arg1, arg2, .. ...

  10. [HDOJ5950]Recursive sequence(递推,二项展开,矩阵快速幂)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950 题意:求解递推式f(n)=f(n-1)+2*f(n-2)+n^4. 写了个小东西,不过我的文章里 ...