数据结构——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 ...
随机推荐
- 字符串replace的理解和练习和配合正则表达式的使用
下面代码展示了(demo地址 https://codepen.io/peach_/pen/jONJjRY): 1.字符串replace的理解和练习和配合正则表达式的使用, 2.正则表达式学习 3.通过 ...
- iOS 动画基础-显式动画
摘要 显式动画 属性动画 CABasicAnimation *animation = [CABasicAnimation animation]; [self updateHandsAn ...
- css 层叠 比较特殊性
css 层叠: 多个相同的css声明(属性),应用到同一个元素上.当一个标签声明冲突时,浏览器会自动出发层叠机制 1:比较优先级 2:比较特殊性 3:比较源次序 依次经过上面的1,2,3的比较后,最终 ...
- 对于vue中axios拦截器简单封装
axios.interceptors.response.use( response => { // 如果返回的状态码为200,说明接口请求成功,可以正常拿到数据 // 否则的话抛出错误 if ( ...
- java ajax上传文件
包括案例 1.springmvc上传 2.ajax上传 3.form表单与文件上传 - 1. http://localhost:8080/ 第一种:springmvc上传- 2. http://loc ...
- java数据类型转换的常见方法
public class Testfun { public static void main(String[] args) { // (一)跨Number父类的类型转换 // 1.str转int =& ...
- python txt文件读写(追加、覆盖)
(1)在lucky.txt中新增内容(覆盖:每次运行都会重新写入内容) f = "lucky.txt" a =8 with open(f,"w") as fil ...
- MVC-区域(Area)
1.启用路由前的准备工作 1.Global.asax.cs中注册路由 public class MvcApplication : System.Web.HttpApplication { protec ...
- Linux/Aix日常报错整理
[root@localhost ~]# umount /mnt umount.nfs: /mnt: device is busy umount.nfs: /mnt: device is busy 问题 ...
- Android笔记(八) Android中的布局——相对布局
RelativeLayout又称为相对布局,也是一种常用的布局形式.和LinearLayout的排列规则不同,RelativeLayout显得更加随意一下,它通常通过相对定位 的方式让控件出现在布局的 ...
