KMP(模板)
kmp算法是解决单模匹配问题的算法,难点在于求next[]数组
求next[]数组:对于子串的所有前缀子串的最长公共前后缀的长度,就是next[]数组的值
首先,要了解两个概念:"前缀"和"后缀"。 "前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。如下图所示:
下面再以”ABCDABD”为例,进行介绍:
”A”的前缀和后缀都为空集,共有元素的长度为0;
”AB”的前缀为[A],后缀为[B],共有元素的长度为0;
”ABC”的前缀为[A, AB],后缀为[BC, C],共有元素的长度0;
”ABCD”的前缀为[A, AB, ABC],后缀为[BCD, CD, D],共有元素的长度为0;
”ABCDA”的前缀为[A, AB, ABC, ABCD],后缀为[BCDA, CDA, DA, A],共有元素为”A”,长度为1;
”ABCDAB”的前缀为[A, AB, ABC, ABCD, ABCDA],后缀为[BCDAB, CDAB, DAB, AB, B],共有元素为”AB”,长度为2;
”ABCDABD”的前缀为[A, AB, ABC, ABCD, ABCDA, ABCDAB],后缀为[BCDABD, CDABD, DABD, ABD, BD, D],共有元素的长度为0。
eg:主串为cbbbaababac 子串为ababac
初始化next[0]=-1;
子串的最长公共前后缀长度
a -->0 next[1]=0 a的前缀为空,后缀也为空,共有元素的长度为0
ab -->0 next[2]=0 ab前缀为[a],后缀为[b],共有元素的长度为0
aba -->1 next[3]=1 前缀为[a,ab],后缀为[a,ba],共有元素的长度为1
abab -->2 next[4]=2 前缀为[a,ab,aba],后缀为[b,ab,bab],共有元素的长度为2
ababa -->3 next[5]=3 前缀为[a,ab,aba,abab],后缀也为[a,ba,aba,baba],共有元素的长度为3
next[i]数组的作用是在当子串字母s[i]在和主串字母p[j]失配的时候,next[i]数组提供一个值,子串整体移动( i-next[i] )个位置,继续用s[next[i]]去和主字母p[j]匹配
eg:模板串是cbbbaababac,子串是ababa
子串下标: 0 1 2 3 4
a b a b a
失配跳转位置next[]: -1 0 0 1 2
这里解释一下:当子串和主串失配的时候,就根据next[]的值移动子串到相应位置去和主串匹配。当子串next[]值为-1的时候,主串的当前匹配位置后移一个字母
这里模拟一下匹配过程,i表示主串的当前匹配位置,j表示子串的当前匹配位置,初始i=0,j=0;主串p[],子串s[]
a!=c ---> i++ i=1,j=0
a!=b ---> i++ i=2,j=0
a!=b ---> i++ i=3,j=0
a!=b ---> i++ i=4,j=0
a==a ---> i++,j++ i=5,j=1
b!=a ---> i保持不变,j=next[j],跳转 i=5,j=0
a==a ---> i++,j++ i=6,j=1
b==b ---> i++,j++ i=7,j=2
a==a ---> i++,j++ i=8,j=3
b==b ---> i++,j++ i=9,j=4
a==a ---> i++,j++ i=10,j=5
j>=strlen(s) 匹配结束 , 返回可以匹配的首地址 return j-i+1
#include<iostream>
#include<string.h>
using namespace std;
char p[],s[];
int next1[];
void get_next(char *s,int *next1)
{
int m=strlen(s);//子串的长度
int j=;//当前匹配的位置
int k=-;//失配的时候要跳转的位置(也是最长公共前后缀的长度)
next1[]=-;
while(j<m)
{
if(k==-||s[j]==s[k])
next1[++j]=++k;
else
k=next1[k];
}
}
int kmp(char *p,char *s)//p是模板串,s是子串
{
int i=,j=;
int n=strlen(p);
int m=strlen(s);
while(i<n&&j<m)
{
if(j==-||p[i]==s[j])
{
i++;
j++;
}
else
j=next1[j];
}
if(j>=m)//s串比较完毕
return i-m+;
else
return -;
} int main()
{
cin>>p>>s;
get_next(p,next1);
for(int i=;s[i];i++)
cout<<"next["<<i<<"]="<<next1[i]<<endl;
cout<<"从第"<<kmp(p,s)<<"个字符开始匹配"<<endl;//返回的是开始匹配的第几个字符,不是位置
return ;
}
KMP(模板)的更多相关文章
- hdu 1686 KMP模板
// hdu 1686 KMP模板 // 没啥好说的,KMP裸题,这里是MP模板 #include <cstdio> #include <iostream> #include ...
- Oulipo HDU 1686 KMP模板
题目大意:求模式串在主串中的出现次数. 题目思路:KMP模板题 #include<iostream> #include<algorithm> #include<cstri ...
- KMP模板(bin)
KMP模板 主要是kuangbin的模板,之后加了一点我的习惯和理解. kmpN() 作用:构造next数组 参数:模式串,模式串长度 kmpC() 作用:返回模式串在主串中出现的次数(可重复) 参数 ...
- HDU 1711 - Number Sequence - [KMP模板题]
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1711 Time Limit: 10000/5000 MS (Java/Others) Memory L ...
- HDU 1711 Number Sequence(KMP模板)
http://acm.hdu.edu.cn/showproblem.php?pid=1711 这道题就是一个KMP模板. #include<iostream> #include<cs ...
- 剪花布条---hdu2087(kmp模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 kmp模板题: #include <cstdio> #include <cst ...
- Oulipo----poj3461(kmp模板)
题目链接:http://poj.org/problem?id=3461 和 减花布条 的题对比一下: 求s2中s1的个数kmp模板: #include<stdio.h> #include& ...
- kmp模板 && 扩展kmp模板
kmp模板: #include <bits/stdc++.h> #define PB push_back #define MP make_pair using namespace std; ...
- kuangbin专题16B(kmp模板)
题目链接: https://vjudge.net/contest/70325#problem/B 题意: 输出模式串在主串中出现的次数 思路: kmp模板 在 kmp 函数中匹配成功计数加一, 再令 ...
- [HDU1711]KMP模板
解题关键:1.直接套kmp模板即可,注意最后输出的位置,需要在索引的位置+1. 2.next用作数组名在oj中会编译错误, 3.选用g++,只有g++才会接受bits/stdc++.h OJ中g++和 ...
随机推荐
- Git管理代码
使用Git管理代码 1. 分支管理模式 首先,master分支应该是非常稳定的,开发都在dev分支上,每个人都有自己的分支,时不时地往dev分支上合并就可以了.完成测试后,再把dev分支合并到mast ...
- XMPPFramework 框架
https://blog.csdn.net/qq_29846663/article/details/70170646 2017-04-14 11:37:02 于海明 阅读数 478更多 分类专栏: i ...
- acm数论之旅(转载)--素数
https://www.cnblogs.com/linyujun/p/5198832.html 前言:好多学ACM的人都在问我数论的知识(其实我本人分不清数学和数论有什么区别,反正以后有关数学的知识我 ...
- 源代码管理工具(1)——SVN(1)——SVN 的使用新手指南,具体到步骤详细介绍----TortoiseSVN
一.客户端的使用: TortoiseSVN(下载地址:https://pan.baidu.com/s/14cAEV5ZfMA9mLlQAb4oznw 这里有包含中文版的语言包). 1.先下载安装(这个 ...
- vue-cli项目结构详解
vue-cli的webpack模板项目配置文件分析 https://blog.csdn.net/hongchh/article/details/55113751/ 由于最近在vue-cli生成的web ...
- MAC系统 - 基础知识
一.基础操作 设置:触控板设置 - >学习具体手势 手势:MacBook Pro手势大全必学手势触控板手势有哪些 左键,右键,滑屏,切换到应用... 一指操作: 一指敲击:鼠标左键: 一指按下: ...
- kafka 消息可靠性
1.消息发送机制 Kafka的ack机制. 当producer向leader发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别: 1(默认):这意味着produc ...
- [ DLPytorch ] 文本分类&图像增强
图像增强 图像增广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模.图像增广的另一种解释是,随机改变训练样本可以降低模 ...
- 【Javaweb】Servlet的xml和注解配置
1.xml <%@ page language="java" contentType="text/html;" %> <!DOCTYPE ht ...
- Day11 - Q - A Multiplication Game HDU - 1517
题目链接 本题很像bash博弈,但又有些许不同,因为这里是乘法,我们可以列出前几项可能 若n=2-9,那么first可以一次取完 若n=10-18,无论first怎么取,second都能一次取完 若n ...