博客
关于我
KMP字符串匹配
阅读量:326 次
发布时间:2019-03-04

本文共 2001 字,大约阅读时间需要 6 分钟。

KMP字符串匹配 ⁡ \operatorname{KMP字符串匹配} KMP

题目链接:

题目

给出两个字符串 s 1 s_1 s1 s 2 s_2 s2 ,若 s 1 s_1 s1 的区间 [ l , r ] [l, r] [l,r] 子串与 s 2 s_2 s2 完全相同,则称 s 2 s_2 s2 s 1 s_1 s1 中出现了,其出现位置为 l l l

现在请你求出 s 2 s_2 s2 s 1 s_1 s1 中所有出现的位置。

定义一个字符串 s s s 的 border 为 s s s 的一个非 s s s 本身的子串 t t t ,满足 t t t 既是 s s s 的前缀,又是 s s s 的后缀。

对于 s 2 s_2 s2 ,你还需要求出对于其每个前缀 s ′ s' s 的最长 border t ′ t' t 的长度。

输入

第一行为一个字符串,即为 s 1 s_1 s1

第二行为一个字符串,即为 s 2 s_2 s2

输出

首先输出若干行,每行一个整数,按从小到大的顺序输出 s 2 s_2 s2 s 1 s_1 s1 中出现的位置。

最后一行输出 ∣ s 2 ∣ |s_2| s2 个整数,第 i i i 个整数表示 s 2 s_2 s2 的长度为 i i i 的前缀的最长 border 长度。

样例输入

ABABABCABA

样例输出

130 0 1

样例解释

在这里插入图片描述

对于 s 2 s_2 s2 长度为 3 3 3 的前缀 ABA,字符串 A 既是其后缀也是其前缀,且是最长的,因此最长 border 长度为 1 1 1

数据范围

Subtask 1 1 1 30 30 30 points): ∣ s 1 ∣ ≤ 15 |s_1| \leq 15 s115 ∣ s 2 ∣ ≤ 5 |s_2| \leq 5 s25

Subtask 2 2 2 40 40 40 points): ∣ s 1 ∣ ≤ 1 0 4 |s_1| \leq 10^4 s1104 ∣ s 2 ∣ ≤ 1 0 2 |s_2| \leq 10^2 s2102
Subtask 3 3 3 30 30 30 points):无特殊约定。
对于全部的测试点,保证 1 ≤ ∣ s 1 ∣ , ∣ s 2 ∣ ≤ 1 0 6 1 \leq |s_1|,|s_2| \leq 10^6 1s1,s2106 s 1 , s 2 s_1, s_2 s1,s2 中均只含大写英文字母。

思路

这道题是一道模板题。

这个KMP的主要思想就是记住你之前匹配时错误的经验。

我们先让 s 2 s_2 s2 s 2 s_2 s2 匹配,得出一个数组 p [ j ] p[j] p[j] ,代表的是当匹配到 s 2 s_2 s2 数组的第 j j j 个字母而第 j + 1 j+1 j+1 个字母不能匹配了时,新的 j j j 最大是多少。
然后就让两个字符串匹配,找到能匹配的,输出出来。

最后要输出 border ,其实就是我们的 p [ j ] p[j] p[j]

那其实就没了。

代码

#include
#include
using namespace std;int asize, bsize, j, p[1000001];char a[1000001], b[1000001];int main() { scanf("%s %s", a + 1, b + 1);//读入 asize = strlen(a + 1);//求出两个字符串的长度 bsize = strlen(b + 1); j = 0; for (int i = 2; i <= bsize; i++) { //s2和s2匹配 while (j && b[i] != b[j + 1]) j = p[j];//匹配不了 if (b[i] == b[j + 1]) j++;//这一个匹配成功 p[i] = j; } j = 0; for (int i = 1; i <= asize; i++) { //s1和s2匹配 while (j && a[i] != b[j + 1]) j = p[j]; if (a[i] == b[j + 1]) j++; if (j == bsize) { printf("%d\n", i - bsize + 1);//匹配的出来 j = p[j]; } } for (int i = 1; i <= bsize; i++) printf("%d ", p[i]);//输出 return 0;}

转载地址:http://vhph.baihongyu.com/

你可能感兴趣的文章
高德网络定位算法的演进
查看>>
高德算法工程一体化实践和思考
查看>>
为亿级用户的美好出行而战!高德地图首届算法大赛落幕 95后北邮在读博士带队夺冠
查看>>
重温网络编程——常识(三)
查看>>
判断一个数是否是2的幂
查看>>
js 闭包(新)
查看>>
vscode 编辑python 如何格式化
查看>>
正则表达针对html(九)
查看>>
seo 回忆录百度基本概念(一)
查看>>
重新整理数据结构与算法(c#)—— 算法套路二分法[二十四]
查看>>
【golang-GUI开发】qt之signal和slot(一)
查看>>
kettle 执行 kjb 临时文件夹 /tmp permission denied 问题
查看>>
Markdown使用笔记
查看>>
「从零单排HBase 06」你必须知道的HBase最佳实践
查看>>
「从零单排canal 04」 启动模块deployer源码解析
查看>>
用ThreadLocal来优化下代码吧
查看>>
netcore中使用session
查看>>
Android 开发学习进程0.25 自定义控件
查看>>
多媒体文件格式全解说(下)--图片
查看>>
淘宝WAP版小BUG分析
查看>>