数据结构——KMP算法
算法介绍
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特—莫里斯—普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。
next数组
我们记主串为字符串S,模式串为字符串P。
我们用next[j]表示以字符Pj结尾的子串的长度相等的前缀字符串与后缀字符串长度的最大值。
特别地,当没有满足条件的子串时,next[j] = 0。
为了方便起见,我们将字符串从下标1开始匹配。如此,next数组所表示的长度就与下标数值相等了。
算法思路
我们从左到右依次枚举S的每一个字符Si,对于当前待匹配字符Si,我们假设当前P字符串中已匹配到Pj。
那么我们只需判断Si和Pj+1,若两者相同,则继续匹配。
若两者不相同,那么我们使j=next[j],即可最大限度的减少匹配次数。因为S字符串的从某位置开始到前i-1的部分与P字符串的前j个字符已匹配(即完全相同),如图中两蓝色直线所夹的S、P的两段,而P1到Pnext[j]部分是长度最大的与以Pj结尾的后缀完全相同的前缀(图中绿色线段),而该以Pj结尾的后缀则必定与S中一段以Si-1结尾的子串完全相同,因而保证了上述操作的正确性。
接下去只需重复上述操作即可。
而对于next数组的预处理,也同上述操作类似,我们只需要以字符串P来匹配字符串P即可。
模板呈现
模板题链接:KMP字符串
代码如下:
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
const int M = 1e5+;
int n,m;
int ne[M];
char s[M],p[M];
int main()
{
cin>>n>>p+;
cin>>m>>s+; for(int i=,j=;i<=n;i++)
{
while(j && p[i]!=p[j+])j=ne[j];
if(p[i]==p[j+])j++;
ne[i]=j;
}
for(int i=,j=;i<=m;i++)
{
while(j && s[i]!=p[j+])j=ne[j];
if(s[i]==p[j+])j++;
if(j==n)
{
printf("%d ",i-n+-);
j=ne[j]; //可有可无,好习惯要加上。若为string,不加会出错。
}
}
printf("\n");
return ;
}
数据结构——KMP算法的更多相关文章
- 数据结构--KMP算法总结
数据结构—KMP KMP算法用于解决两个字符串匹配的问题,但更多的时候用到的是next数组的含义,用到next数组的时候,大多是题目跟前后缀有关的 . 首先介绍KMP算法:(假定next数组已经学会, ...
- 实验数据结构——KMP算法Test.ming
翻译计划 小明初学者C++,它确定了四个算术.关系运算符.逻辑运算.颂值操作.输入输出.使用简单的选择和循环结构.但他的英语不是很好,记住太多的保留字,他利用汉语拼音的保留字,小屋C++,发明 ...
- 数据结构-kmp算法
定义 改进字符串的匹配算法 关键:通过实现一个包含了模式串的局部匹配信息的next()函数,利用匹配失败的信息,减少匹配次数. 1.BF算法 暴力匹配 给定 文本串S "BBC ABCDAB ...
- <数据结构>KMP算法
next数组 定义 严格定义:next[i]表示使子串s[0...k] == s[i-k...i]的最大的k(前后缀可以重叠,但不能是s[0..i]本身) 含义:最长相等前后缀的下标,没有则赋-1 图 ...
- 大话数据结构——KMP算法(还存在问题)
http://www.ruanyifeng.com/blog/2013/05/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm.html /*#include& ...
- 数据结构KMP算法中手算next数组
总结一下今天的收获(以王道数据结构书上的为例子,虽然我没看它上面的...):其中竖着的一列值是模式串前缀和后缀最长公共前缀. 最后求得的结果符合书上的结果,如果是以-1开头的话就不需要再加1,如果是以 ...
- 数据结构- 串的模式匹配算法:BF和 KMP算法
数据结构- 串的模式匹配算法:BF和 KMP算法 Brute-Force算法的思想 1.BF(Brute-Force)算法 Brute-Force算法的基本思想是: 1) 从目标串s 的第一个字 ...
- 数据结构与算法--KMP算法查找子字符串
数据结构与算法--KMP算法查找子字符串 部分内容和图片来自这三篇文章: 这篇文章.这篇文章.还有这篇他们写得非常棒.结合他们的解释和自己的理解,完成了本文. 上一节介绍了暴力法查找子字符串,同时也发 ...
- 【数据结构】KMP算法
我还是不太懂... 转2篇大神的解释 1>https://www.cnblogs.com/yjiyjige/p/3263858.html 2>https://blog.csd ...
随机推荐
- Spark机器学习基础-特征工程
对连续值处理 0.binarizer/二值化 from __future__ import print_function from pyspark.sql import SparkSession fr ...
- vue实现一个评论列表
<!DOCTYPE html> <html> <head> <title>简易评论列表</title> <meta charset=& ...
- 常见User-Agent大全
window.navigator.userAgent 1) Chrome Win7: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.1 (KH ...
- C#-FileHelper
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 国内首本免费深度学习书籍!还有人没Get么?
这本书的作者很有趣鸭. 一开篇别的不说,先跟大家讲哲学,讨论人工智能实现的可能性.摘录一些他的结论: 人工智能可以实现 自由意志并不存在 量子力学并不能证明自由意志的存在 幸福感和物质水平提高并没有绝 ...
- Django:CSRF(Cross-request forgery)跨站请求伪造
一.CSRF是什么 二.CSRF攻击原理 三.CSRF攻击防范 一.CSRF是什么 CSRF(Cross-site request forgery)跨站请求伪造,也被称为“One Click Atta ...
- Keras Conv1d 参数及输入输出详解
Conv1d(in_channels,out_channels,kernel_size,stride=1,padding=0,dilation=1,groups=1,bias=True) filter ...
- 0018SpringBoot连接docker中的mysql并使用druid数据源
由于druid数据源自带监控功能,所以引用druid数据源 1.centos7中安装并启动docker 2.docker安装并启动mysql 3.pom.xml中引入druid依赖 4.applica ...
- NodeJS开发博客(三) 数据的保存
什么是cookie 存储在浏览器的一段字符串(最大5k) 跨域不共享 格式如 k1=v1 k2=v2 因此可以存储结构化数据 每次发送http请求,会将请求域的cookie一起发送给server se ...
- python_面向对象——编程步骤
校园管理系统: 设计一个学校机构管理系统,有总部.分校.有学院.老师.员工,实现具体如下需求: 1.有多个课程,课程要有定价 2.有多个班级,班级跟课程有关联 3.有多个学生,学生报名班级,交这个班级 ...