KMP:

KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是实现一个next()函数,函数本身包含了模式串的局部匹配信息。时间复杂度O(m+n)。

——百度百科。

自我理解:

kmp算法最最最最核心的思想,就是在每一次失去匹配的时候,找到最大的可能能够匹配的子段进行匹配。

也就是著名的nxt数组。

算法流程:

数组只介绍一个nxt数组。nxt[i]表示,从1~i前缀S中,最长的前缀等于后缀的长度(不能是S)。

在每次失去匹配的时候,因为上次已经能够匹配到j了,所以1~j和 i-j~i-1 是相等的。

所以我们让j=nxt[j]的时候,根据定义,1~nxt[j] = j-nxt[j]+1~j , 又因为:1~j = i-j~i-1 所以 j-nxt[j]+1 ~ j = i-nxt[j] ~ i-1

这样,我们退一步到nxt,可以找到失去匹配后,最大的可能再次匹配上的字段长度nxt[j]

代码实现:

void kmp(){
nxt[]=;
for(int i=,j=;i<=l2;i++){
while(j>&&b[i]!=b[j+]) j=nxt[j];
if(b[i]==b[j+]) j++;
nxt[i]=j;
}
}

下面这里还加上了f数组,f[i]表示,在a串中,以第i位结尾的所有子串,和b串的前缀最大匹配的长度。

转移是类似的。

void fin(){
for(int i=,j=;i<=l1;i++){
while(j>&&(j==l2||a[i]!=b[j+])) j=nxt[j];
if(a[i]==b[j+]) j++;
f[i]=j;
if(f[i]==l2){
printf("%d\n",i-l2+);
}
}
}

这样就可以求出模式串在原始串中出现的位置和个数了。

应用:

1.模式串在主串中出现的次数。见上述代码。
2.求一个串的循环节:
长度为n的字符串的最短循环节是:n-nxt[n],(可以证明:1.可以循环 2.是最短的)

当n%(n-nxt[n])等于0的时候,字符串是一个循环字符串。最长循环次数为:n/(n-nxt[n])

应用例题:

T1:NOI2014 动物园

这个题考察S的前缀中,处理不重叠前缀等于后缀的数量。

可以先求出重叠的nxt[i],num1[]

在处理不重叠的num2[]的时候,跳nxt[j]的时候,跳跃不停止的条件加上一个2*j>i还要跳,因为不能重叠。

跳完后,判断能否加1,如果2*j>i再跳一次。(WA了。。。)

最后,num2[i]=num1[j]+1 注意,这里一定是num1,也就是可重叠的。因为2*j<=i,所以,j中重叠是没有关系的。(WA了。。。)

加一表示1~j和i-j+1~i也是一个。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+;
const int mod=1e9+;
int nxt1[N],nxt2[N],num1[N],num2[N];//1: can 2: can't folded
char a[N];
int l;
ll ans;
void kmp1(){
nxt1[]=,num1[]=;
for(int i=,j=;i<=l;i++){
while(j&&a[i]!=a[j+]) j=nxt1[j];
if(a[i]==a[j+]) j++;
nxt1[i]=j;
if(nxt1[i]) num1[i]=num1[j]+;
}
}
void kmp2(){
nxt2[]=;num2[]=;
for(int i=,j=;i<=l;i++){
while(j&&(*j>i||a[i]!=a[j+])) j=nxt1[j];//warning!!
if(a[i]==a[j+]) j++;
if(*j>i) j=nxt1[j];//warning!!
nxt2[i]=j;
if(nxt2[i]) num2[i]=num1[j]+;
}
}
int main()
{
int n;
scanf("%d",&n);
while(n--){
scanf("%s",a+);
ans=;
l=strlen(a+);
kmp1();
kmp2();
for(int i=;i<=l;i++){
ans=(ans*((ll)+num2[i]))%mod;
}
printf("%lld\n",ans);
memset(num1,,sizeof num1);
memset(num2,,sizeof num2);
}
return ;
}

动物园

T2:bzoj4641 基因改造

KMP 模式串匹配 失去匹配的瞬间你还有什么的更多相关文章

  1. kmp模式串匹配

    大二的时候百度看不懂,现在大三下学期了百度也看不懂.(实在是不能理解这个next数组究竟是怎么样工作的,为什么会得出那样的结果.)如果有好心人知道的话希望可以联系我告诉我(邮箱:4609019410@ ...

  2. 模式串匹配KMP详解

    关于KMP模式串匹配网上蛮多的. 对于KMP有自己理解所以写下来希望能够对你们的学习有帮助. 之前暑假的时候学过,然后好长时间没用发现又忘了,现在再看看发现有了新的理解. ============== ...

  3. hdu 1686 Oulipo 【KMP】(计算模式串匹配的次数——与已匹配的字串可以有交集)

    题目链接:https://vjudge.net/contest/220679#problem/B 题目大意: 输入一个T,表示有T组测试数据: 每组测试数据包括一个字符串W,T,T长度大于W小于100 ...

  4. 单模式串匹配----浅谈kmp算法

    模式串匹配,顾名思义,就是看一个串是否在另一个串中出现,出现了几次,在哪个位置出现: p.s.  模式串是前者,并且,我们称后一个 (也就是被匹配的串)为文本串: 在这篇博客的代码里,s1均为文本串, ...

  5. 模式串匹配之KMP算法

    模式串匹配之KMP算法 KMP算法 模式值计算(next[j]) (1) next[0]=-1,  第一个字符模式值为-1 (2) next[j]=-1, T中下标为j的字符与首字符相同,且j前面的1 ...

  6. C++编程练习(7)----“KMP模式匹配算法“字符串匹配

    子串在主串中的定位操作通常称做串的模式匹配. KMP模式匹配算法实现: /* Index_KMP.h头文件 */ #include<string> #include<sstream& ...

  7. HDU-2087-剪花布条 【KMP】(求模式串的匹配个数——与已匹配的字串不交)

    题目链接:https://vjudge.net/contest/220679#problem/C 剪花布条                                               ...

  8. AC自动机——多模式串匹配的算法思想

    标准KMP算法用于单一模式串的匹配,即在母串中寻求一个模式串的匹配,但是现在又存在这样的一个问题,如果同时给出多个模式串,要求找到这一系列模式串在母串存在的匹配个数,我们应该如何处理呢? 基于KMP算 ...

  9. POJ 3167 Cow Patterns(模式串浮动匹配)

    题目链接:http://poj.org/problem?id=3167 题意:模式串可以浮动的模式匹配问题给出模式串的相对大小,需要找出模式串匹配次数和位置. 思路:统计比当前数小,和于当前数相等的, ...

随机推荐

  1. 【工作感悟】Android 开发者,如何提升自己的职场竞争力?

    前言 该文章是笔者参加 Android 巴士线下交流会成都站 的手写讲稿虚拟场景,所以大家将就看一下. 开始 大家好,我是刘世麟,首先感谢安卓巴士为我们创造了这次奇妙的相遇.现场的氛围也让我十分激动. ...

  2. Socket异步通信及心跳包同时响应逻辑分析(最后附Demo)。

    有段时间没有更博了,刚好最近在做Socket通信的项目,原理大致内容:[二维码-(加logo)]-->提供主机地址和端口号信息(直接使用[ThoughtWorks.QRCode.dll]比较简单 ...

  3. 如何手动写一个Python脚本自动爬取Bilibili小视频

    如何手动写一个Python脚本自动爬取Bilibili小视频 国庆结束之余,某个不务正业的码农不好好干活,在B站瞎逛着,毕竟国庆嘛,还让不让人休息了诶-- 我身边的很多小伙伴们在朋友圈里面晒着出去游玩 ...

  4. Tomcat通过自带的Cluster方式实现Session会话共享环境操作记录

    一般来说,在多个tomcat集群业务中,session会话共享是必须的需求,不然前端nginx转发过来的请求不知道之前请求在哪台tomcat节点上,从而就找不到session以至于最终导致请求失败.要 ...

  5. javascript DOM操作中的insertAdjacentHTML方法

    插入HTML内容与文本内容以前用的是innerHTML与innerText方法,今天看到insertAdjacentHTML和 insertAdjacentText两个API,特地学习一下: inse ...

  6. IDEA启动服务阻塞,断点过程十分慢的问题

    使用debug无法启动项目但是使用run就可以启动程序,而且启动比以前的debug模式快的多 原因: 启动不了的原因是在项目中的方法上打了断点,导致项目无法继续编译 取消方法断点就可以了 在idea官 ...

  7. PAT L2-011 玩转二叉树

    https://pintia.cn/problem-sets/994805046380707840/problems/994805065406070784 给定一棵二叉树的中序遍历和前序遍历,请你先将 ...

  8. TDD中测试替身学习总结

    在使用TDD开发时,经常会遇到需要被测对象需要依赖其他子系统的情况,但是你希望将测试代码跟依赖项隔离,以保证测试代码仅仅针对当前被测对象或方法展开,这时候你需要的是测试替身.测试替身可以分为四类:- ...

  9. Bootstrap 引入文件顺序及IE兼容性js

    <!DOCTYPE html><html lang="zh-cn"><head> <meta charset="utf-8&qu ...

  10. centos7黑客帝国装逼

    黑客帝国既视感 搜 cmatrix 然后放到本地解压缩 ,安装 yum install ncurses-devel./configure && make && make ...