扩展的KMP算法,可以在Ο(n + m)的时间复杂度内计算出模板串与文本串的每一个后缀的最长公共前缀,即LCP(T[i:n],P)。

KMP算法所解决的单模板字符串匹配问题,求得的匹配点是LCP = m的位置,属于该算法的子问题。扩展的KMP算法可以获得更多信息。

定义:文本串长度为n,模板串长度为m

   next[i]:模板串P[i:m]和P的最长公共前缀

   extend[i]:文本串T[i:n]和P的最长公共前缀(待求)

   习惯上使用左闭右开区间,下标从0开始,字符串采用Python的表示法

算法思想:

最大程度利用已匹配的串的信息

算法思路:

假设我们已知了next数组,且当前已知T[p:mx]与P的前缀是匹配的。

设mx表示文本串当前已匹配到的最末位置的下一位置(代比较的位置),p表示与之匹配的模板串与文本串的对齐位置,i表示当前要计算extend值的位置

比较i+next[i-p]与mx的大小关系,分为两种情况

  • if (i + next[i - p] < mx)

如图,我们知道p到mx这一段的文本串与模板串是相等的,根据模板串自身的next数组可以知道文本串的extend值至少是next[i - p],又next数组的定义是“最长”,即确定了下一位不相等。所以extend[i] = next[i - p]

  • else

当i + next[i - p] >= mx时,模板串p-i位置的最长公共前缀超出了已知的文本串的范围。我们最大程度地利用已知信息,i位置的extend长度就应当从mx-i开始扩展,接下来比较T[mx]和P[mx - i](标✦的位置),更新答案和mx、p的值。

匹配算法完毕。接下来我们要考虑模板串的next数组的求法

注意到,   next是模板串与模板串的LCP

      extend是文本串与模板串的LCP

所以——next的生成其实就是自己对自己套用该算法。我们甚至不需要改变代码,只需令T=P,带入函数即可。

实现细节

#1由于模板串在匹配自身时在初始位置完全相同,要避免mx在一开始就跳到末尾,所以要加个特判,当匹配自身时,要跳过第一位开始比较。

#2当i>=mx时要更新mx的值为i,重返暴力操作


模板题:洛谷P5410

AC代码:

void exKMP(const char* P, int* nxt, const char* T, int* ext)  P为模板串,nxt是模板串的next数组,T为文本串,ext储存待求的extend值;当ext==nxt时判断为匹配自身,启动特判

 #include <iostream>
#include <string>
#include <cstring>
#include <iterator>
using namespace std; const int maxn = 1e5 + ;
int nxtP[maxn], Lcp[maxn];
void exKMP(const char* P, int* nxt, const char* T, int* ext) {
int i, mx = , p = , n = strlen(T), m = strlen(P); //mx: Position where doesn't fit.
if (nxt == ext) {
ext[] = n;
p = ; mx = ; i = ;
while (mx < n && mx - i < m && T[mx] == P[mx - i]) mx++;
} else i = ; for (; i < n; ++i)
if (nxt[i - p] + i < mx) ext[i] = nxt[i - p];
else {
if (i >= mx) mx = i; //i >= mx
while (mx < n && mx - i < m && T[mx] == P[mx - i]) mx++;
ext[i] = mx - i;
p = i;
}
return;
}
signed main() {
string T, P;
cin>>T>>P;
exKMP(P.data(), nxtP, P.data(), nxtP);
exKMP(P.data(), nxtP, T.data(), Lcp);
copy(nxtP, nxtP + P.length(), ostream_iterator <int> (cout, " "));
cout<<endl;
copy(Lcp, Lcp + T.length(), ostream_iterator <int> (cout, " "));
return ;
}

扩展的KMP算法图解的更多相关文章

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

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

  2. KMP算法图解

    字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...

  3. 扩展KMP算法

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

  4. 扩展KMP算法小记

    参考来自<拓展kmp算法总结>:http://blog.csdn.net/dyx404514/article/details/41831947 扩展KMP解决的问题: 定义母串S和子串T, ...

  5. KMP算法模板&&扩展

    很不错的学习链接:https://blog.csdn.net/v_july_v/article/details/7041827 具体思路就看上面的链接就行了,这里只放几个常用的模板 问题描述: 给出字 ...

  6. 神奇的字符串匹配:扩展KMP算法

    引言 一个算是冷门的算法(在竞赛上),不过其算法思想值得深究. 前置知识 kmp的算法思想,具体可以参考 → Click here trie树(字典树). 正文 问题定义:给定两个字符串 S 和 T( ...

  7. 图解算法——KMP算法

    KMP算法 解决的是包,含问题. Str1中是否包含str2,如果包含,则返回子串开始位置.否则返回-1. 示例1: Str1:abcd123def Str2:123d 暴力法: 从str1的第一个字 ...

  8. hdu 4300 kmp算法扩展

    Clairewd’s message Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  9. 初探KMP算法

            数据结构上老师也没讲这个,平常ACM比赛时我也没怎么理解,只是背会了代码--前天在博客园上看见了一篇介绍KMP的,不经意间就勾起了我的回忆,写下来吧,记得更牢. 一.理论准备      ...

随机推荐

  1. 【实验】ssh私钥泄露

    翻自己的笔记看到之前做过的一个实验,一个关于ssh私钥泄露的实验,贴出来与大家交流. 做这种题脑洞需要特别大,而且也需要运气. 1.实验环境准备 2.实验流程 1)探测信息 用namp进行端口扫描,扫 ...

  2. 第一次打开PyCharm的基本操作(附图)

    第一次打开PyCharm可能需要修改一些个性化和了解一些基本操作,有助于接下来的学习过程.(后续可能会更新) 我的版本是64位的1.3 1.换界面皮肤 默认黑色的,不喜欢黑色皮肤可以换成白色的 Fil ...

  3. UiPath工具取得网页上面的数据,写入到csv,Outlook邮件发送

    问题描述: 想取得网页上面的股票价格,之后写入到csv文本里面之后添加附件发送邮件. 解决方法: 利用UIPath工具来取得数据,之后写入再发送. 具体步骤: 1.打开网页,之后找到所显示的股票行情的 ...

  4. mongdb学习

    1.启动mongdb 服务(注启动之前把data 文件夹清空) 2.开发和jpa一样 只是extendMongoRepository 3.实体类只有id注解,属性全为String

  5. 关于MyBatis传入String用于test判断的坑

    不要在心情糟糕的时候写代码,能坑死自己. 今天码代码的时候出现一个问题,脾气暴躁到砸桌子, 在Mybatis传入参数为String并且用 if test 判断的过程中发现 <if test=&q ...

  6. 猴子补丁(Monkey Patching)

    猴子补丁是我在面试的时候接触的一到题,学python的时候,我根本就没有听说这个概念!那接下来我们来分析一下: 1.什么是猴子补丁? 2.猴子补丁的功能? 3.猴子补丁的应用场景? 一.什么是猴子补丁 ...

  7. PHP二维数组的引用赋值容易犯的错误

    大家一起来分析一下下面这段代码: <?php $arr = array(); $arr["abc"] = array("sex" => 100, & ...

  8. VMware安装windows2003

    一.安装vm 这一项大家应该都会,网上也有很多教程. 二.搭建Windows server 2003 1.镜像下载- 2.虚拟机安装 首先是新建虚拟机,我选的是自定义,也可以选典型 第一步默认下一步, ...

  9. asp.net MVC 抓取微信文章数据(正文)

    1.抓微信的正文主要是调用第三方的接口(https://market.aliyun.com/products/56928004/cmapi012134.html) using Newtonsoft.J ...

  10. 夯实基础:彻底搞清楚Cookie 和 Session 关系和区别(转)

    原文地址:http://www.sohu.com/a/281228178_120047080 网络请求中的cookie与set-Cookie的交互模式和作用:https://my.oschina.ne ...