把已经给出的串称为文本串,要在文本串中找的串称为模式串。特别地,前两位$(kmp[0],kmp[1])$为零。比如串$ABABAC$,它的$fail$应该为001230。
已知第$i$位的自动机$kmp[i]$,要求第$i+1$位的。设$j=kmp[i]$。$kmp[i]$一定在i前面,$kmp[i]$已经求好了。如果字符串的$i$和$j+1$位不同$(s2[i]≠s2[j+1])$,那么j不断地跳到自己的自动机$kmp[j]$,直到匹配上或$j=0$为止。如果匹配上,$f[i] = j+1$;否则如果还是$s2[i]≠s2[j+1]$,说明是$j=0$而不是匹配上了,那么$kmp[j] = 0$。

构建自动机:

  j=;
for (int i=;i<=lb;i++){
while(j&&b[i]!=b[j+])
//此处判断j是否为0的原因在于,如果回跳到第一个字符就不 用再回跳了
j=kmp[j];
//通过自己匹配自己来得出每一个点的kmp值
if(b[j+]==b[i])j++;
kmp[i]=j;
//i+1失配后应该如何跳
}

我们已经对该子串构建了一个自动机,当两个字符串相比较,如果失配,即$s1[i]!=s2[j+1]$就跳回,此时一定两位匹配$(j!=0)$或从头开始$(j=0)$,之后再匹配下一位即可。

运行自动机:

   int j;
j=;//j可以看做表示当前已经匹配完的模式串的最后一位的位置
//也可以理解为j表示模式串匹配到第几位了
for(int i=;i<=la;i++){
while(j&&b[j+]!=a[i])j=kmp[j];
//如果失配 ,那么就不断向回跳,直到可以继续匹配
if (b[j+]==a[i]) j++;
//如果匹配成功,那么对应的模式串位置++
if (j==lb) {
cout<<i-lb+<<endl;
j=kmp[j];
//继续匹配
}
}

完整代码:

 #include<iostream>
#include<cstring>
#define MAXN 1000010
using namespace std;
int kmp[MAXN];
int la,lb,j;
char a[MAXN],b[MAXN];
int main()
{
cin>>a+;
cin>>b+;
la=strlen(a+);
lb=strlen(b+);
for (int i=;i<=lb;i++)
{
while(j&&b[i]!=b[j+])
j=kmp[j];
if(b[j+]==b[i])j++;
kmp[i]=j;
}
j=;
for(int i=;i<=la;i++)
{
while(j>&&b[j+]!=a[i])
j=kmp[j];
if (b[j+]==a[i])
j++;
if (j==lb) {cout<<i-lb+<<endl;j=kmp[j];}
} for (int i=;i<=lb;i++)
cout<<kmp[i]<<" ";
return ;
}

Kmp--P3375 【模板】KMP字符串匹配的更多相关文章

  1. P3375 模板 KMP字符串匹配

    P3375 [模板]KMP字符串匹配 来一道模板题,直接上代码. #include <bits/stdc++.h> using namespace std; typedef long lo ...

  2. 洛谷P3375 [模板]KMP字符串匹配

    To 洛谷.3375 KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果 ...

  3. 【模板】字符串匹配的三种做法(Hash、KMP、STL)

    题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 输入输出格式 输入格式: 第一行为一个字符串,即为s1 第二行为一个字符串,即为s2 输出格式: 1行 ...

  4. 字符串KMP——用途广泛的字符串匹配算法 + 扩展KMP——特殊定义的字符串匹配

    引 入 引入 引入 " SY 和 WYX 在看毛片.(几 毛 钱买到的动作 片,毛 片) WYX 突然想回味一个片段,但是只记得台词里面有一句挺长的 " ∗ ∗ ∗ ∗ **** ...

  5. 字符串匹配Boyer-Moore算法:文本编辑器中的查找功能是如何实现的?---这应该讲的最容易懂的文章了!

    关于字符串匹配算法有很多,之前我有讲过一篇 KMP 匹配算法:图解字符串匹配 KMP 算法,不懂 kmp 的建议看下,写的还不错,这个算法虽然很牛逼,但在实际中用的并不是特别多.至于选择哪一种字符串匹 ...

  6. P3375 【模板】KMP字符串匹配

    P3375 [模板]KMP字符串匹配 https://www.luogu.org/problemnew/show/P3375 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在 ...

  7. 洛谷—— P3375 【模板】KMP字符串匹配

    P3375 [模板]KMP字符串匹配 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next. (如 ...

  8. KMP字符串匹配 模板 洛谷 P3375

    KMP字符串匹配 模板 洛谷 P3375 题意 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.(如果 ...

  9. 洛谷P3375 - 【模板】KMP字符串匹配

    原题链接 Description 模板题啦~ Code //[模板]KMP字符串匹配 #include <cstdio> #include <cstring> int cons ...

  10. P3375【模板】KMP字符串匹配

    前言: 额……很久以前就写了KMP模板(只是半知不解),话说看完了manacher,再回过头看KMP,是真TM简单啊!字符串专题整体较抽象,所以必须牢记思路并时常复习 题目描述 如题,给出两个字符串s ...

随机推荐

  1. swoole之异步文件IO

    一.代码部分 读: <?php /** * 异步文件系统仅限于4.3.0之前的版本 * 读取文件 */ $filename = dirname(__FILE__).DIRECTORY_SEPAR ...

  2. Typora: Markdown Reference (Typora下Markdown语法使用说明)

    引言 由于一直在使用Typora,这个是我使用过的最棒的Markdown编辑器,但是总是忽略某一个功能,于是决定认真看一下其帮助文档 这里做一个简单主要功能的中文翻译(按键对应Windows下). 标 ...

  3. linux7下nenux3.14的maven私服搭建和配置使用

    为什么用私服,各种帖子很多,话不多说,直接奉上本博主的搭建过程. 一.环境准备:确保jdk和maven安装完成 二.下载nenux:地址:https://www.sonatype.com/downlo ...

  4. PHP代码审计之入门实战

    系统介绍 CMS名称:新秀企业网站系统PHP版 官网:www.sinsiu.com 版本:这里国光用的1.0 正式版 (官网最新的版本有毒,网站安装的时候居然默认使用远程数据库???迷之操作 那站长的 ...

  5. Mysql数据库的简单介绍与入门

    Mysql数据库的简单介绍与入门 前言 一.下载与安装 1.下载 官网下载MYSQL5.7.21版本,链接地址https://www.mysql.com/downloads/.下载流程图如下: 找到M ...

  6. Job for nginx.service failed because the control process exited with error code. See “systemctl stat

    启动nginx服务时如果遇到这个错误 Job for nginx.service failed because the control process exited with error code. ...

  7. Charles抓包(HTTP)

    一.电脑抓包: 安装Charles,打开Charles即可 二.手机抓包: 设置手机WiFi配置代理即可:(确保电脑和手机在同一个网络) 三.拦截请求: 四.修改请求/返回: 打上断点后,刷新页面,在 ...

  8. java第三周

  9. Java多线程之以7种方式让主线程等待子线程结束

    记一次主线程等待子线程结束的多种方法的学习 在学习多线程时,最开始遇到的问题其实是"计算子线程运行时间",写到最后发现本文和标题更为符合,但是仍然基于问题:"在主线程中获 ...

  10. Linux每日练习-awk命令的内外部变量传递20200225