当前位置:网站首页>KMP匹配字符串
KMP匹配字符串
2022-07-04 04:24:00 【sheep.ice】
一、前言
这一章记录的是自己学习KMP算法的一个笔记吧。我觉得KMP虽然目前没有用到相关的算法,但是他的思想很妙,很多人在刚开始会非常不理解这个算法的由来。而我也是写了好几遍才能够真的说掌握了一些KMP算法。其实主要记住一点就是,KMP完成了字符串与本身进行比较的一个思路。
所有字符串下标从1开始
二、相关操作
①相关变量的定义

说真的我觉得相关一些数组的定义是整个这个算法的核心
首先就是题目给的两个串,一个比较长的叫做模式串,另外一个叫做子串,题目的要求就是子串在模式串出现的位置或者出现的次数
我们再看最难理解的一个ne数组的定义,最长子串的公共前后缀长度
其实这个地方需要加上一个定义,假设ne[X], 这个其实代表的是,子串从1-X位置的字符串的最长公共前后缀的长度。这里要说明的是,前后缀是什么
- 前缀:包含字符串首字母的连续子串
- 后缀:包含字符串尾字母的连续子串
比如字符串:abc
前缀有: a ab
后缀有: c bc
②ne数组的求解
搞清楚了前后缀之后,如果我们要去求ne数组怎么求呢?

假设我们有一个字符串:abcabf
a : 0
ab : 0
abc : 0
abca : a为公共前后缀 1
abcab: ab为公共前后缀 2
abcabf: 0
而上方求出这样一个数组便是去比较p字符串的本身,匹配图如下:

代码如下:
for(int i = 2, j = 0; i <= n; i ++ ) {
while(j != 0 && p[j + 1] != p[i]) j = ne[j];
if(p[j + 1] == p[i]) j ++ ;
ne[i] = j;
}
③字符串匹配
为什么求出一个ne数组就可以拿来进行匹配了呢?

这个是我最常用进行的一个理解图
我们可以看到有两个子串
- q : abcabcabf
- p : abcabf
当p匹配到f的时候发现不相等了,那么子串p重新开始匹配的位置是由ne数组进行指示的,f位置前一个位置是b,b的ne值为2,代表此位置的公共前后缀的长度为2,那么我们需要先回到2的位置,也就是p串中的b位置,再看b后面的c是否与上面串相等。相等之后继续往后推移匹配p的串的指针j,知道j指针的值等于p的长度,说明已经匹配成功了。
上面之所以能进行,其实就是因为,p利用ne指针去指示已经匹配过的前缀,我们不再进行重新匹配,而是从匹配好的前缀再重新开始,也就是说,abf和q串的abc字串不相等了,但是abc已经完全匹配好了ab后缀,那我的p串刚好有个ab前缀,那我们直接从ab这个前缀的位置再继续往后匹配,这样就避免了重复匹配的时间复杂度!
三、相关题目

完整AC代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 100050, M = 10 * N;
char p[N], q[M];
int ne[N];
int main() {
//进行相关输入
int n, m;
cin >> n >> (p + 1) >> m >> (q + 1);
//先进性ne数组的求解
for(int i = 2, j = 0; i <= n; i ++ ) {
while(j != 0 && p[j + 1] != p[i]) j = ne[j];
if(p[j + 1] == p[i]) j ++ ;
ne[i] = j;
}
//进行字符串的匹配
for(int i = 1, j = 0; i <= m; i ++ ) {
while(j != 0 && p[j + 1] != q[i]) j = ne[j];
if(p[j + 1] == q[i]) j ++ ;
if(j == n) {
cout << i - n << " ";
j = ne[j];
}
}
return 0;
}
边栏推荐
- Zkevm (12) state proof of appliedzkp
- 【MATLAB】MATLAB 仿真数字带通传输系统 — QPSK 和 OQPSK 系统
- 中科磐云—2022广西逆向解析思路
- Solve the problem of failed to load property source from location 'classpathapplication YML 'problem
- 网络设备应急响应指南
- Correct the classpath of your application so that it contains a single, compatible version of com.go
- Annex V: briefing on the attack process docx
- 关闭的数据能用dbca删除吗? 能
- 【MATLAB】通信信号调制通用函数 — 傅里叶变换
- 关于solidworks standard无法获得许可 8544问题的总结
猜你喜欢

定制一个自己项目里需要的分页器

Talking about JVM

令人头痛的延时双删

如何构建属于自己的知识引擎?社群开放申请

2022广东省赛——编码信息获取 解析flag

电子元器件商城与数据手册下载网站汇总

在代碼中使用度量單比特,從而生活更美好

Utiliser des unités de mesure dans votre code pour une vie meilleure

Use units of measure in your code for a better life

Notes on the paper "cross view transformers for real time map view semantic segmentation"
随机推荐
【MATLAB】MATLAB 仿真数字基带传输系统 — 双极性基带信号(第 I 类部分响应波形)的眼图
Beipiao programmer, 20K monthly salary, 15W a year, normal?
Capturing and sorting out external Fiddler -- Conversation bar and filter
qt下开发mqtt的访问程序
网络设备应急响应指南
Unity中RampTex介绍和应用: 溶解特效优化
Correct the classpath of your application so that it contains a single, compatible version of com. go
The paddlehub face recognition scheme is deployed, and the trained model is deployed and applied in pytchrom
附件六:防守工作簡報.docx
RPC - gRPC简单的demo - 学习/实践
【MATLAB】MATLAB 仿真 — 模拟调制系统 之 AM 调制过程
附件一:202x年xxx攻防演习授权委托书
Unity 接入天气系统
Several smart watch related chips Bluetooth chip low power consumption
分享一些我的远程办公经验
简单g++和gdb调试
Error response from daemon: You cannot remove a running container 8d6f0d2850250627cd6c2acb2497002fc3
红队视角下的防御体系突破之第一篇介绍、阶段、方法
2022年6月总结
附件四:攻击方评分标准.docx