当前位置:网站首页>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;
}
边栏推荐
- When using flash to store parameters, the code area of flash is erased, which leads to the interrupt of entering hardware error
- 自动化测试selenium基础篇——webdriverAPI
- Change the background color of Kivy tutorial (tutorial includes source code)
- Annexe VI: exposé sur les travaux de défense. Docx
- Encryption and decryption
- qt下开发mqtt的访问程序
- CRS-4013: This command is not supported in a single-node configuration.
- Sample template of software design document - learning / practice
- 电子元器件商城与数据手册下载网站汇总
- [matlab] matlab simulation - low pass Gaussian white noise
猜你喜欢

Create ASM disk through DD

2022年6月总结

Flutter ‘/usr/lib/libswiftCore.dylib‘ (no such file)

软件设计文档示例模板 - 学习/实践

2022 Guangdong provincial competition - code information acquisition and analysis flag

C basic (VII) document operation

Annexe VI: exposé sur les travaux de défense. Docx

GUI application: socket network chat room

郑州正清园文化传播有限公司:针对小企业的7种营销技巧

Zhongke panyun-d module analysis and scoring standard
随机推荐
[matlab] matlab simulation - low pass Gaussian white noise
How do good test / development programmers practice? Where to go
Detailed comparison of Hynix emmc5.0 and 5.1 series
附件六:防守工作简报.docx
PostgreSQL 正式超越 MySQL,这家伙也太强了吧!
2022年6月总结
rac删除损坏的磁盘组
Public inputs in appliedzkp zkevm (13)
Acwing game 58
Using jsts in esmodule environment
YoloV6实战:手把手教你使用Yolov6进行物体检测(附数据集)
Annexe VI: exposé sur les travaux de défense. Docx
RAC delete damaged disk group
加密和解密
【Go】数据库框架gorm
Kivy tutorial 07 component and attribute binding implementation button button click to modify the label component (tutorial includes source code)
自动化测试selenium基础篇——webdriverAPI
appliedzkp zkevm(13)中的Public Inputs
Test cs4344 stereo DA converter
【无标题】