KMP 算法详解
之前模模糊糊的理解了KMP,结果由于并不是完全弄清楚而导致自己在一道题目上疯狂的T,似乎是next函数写的有问题,于是痛心疾首的回来写一篇报告,警示自己
对KMP来说,匹配串的next数组是重中之重,通过next的跳跃,大大提高了匹配的速度
那么首先next 是什么呢?一句话的事情
这次没配上,下一次找谁配
换句话说,就是
当next[i] 大于 0 时,第 i 位的数字不一定与字符串的开头的相应位置匹配上
举个栗子
首先next[0] = -1 //第一个点都匹配不上当然就回家吃饭了啊
|
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
|
a |
b |
a |
b |
a |
b |
c |
c |
c |
c |
|
-1 |
0 |
0 |
1 |
2 |
3 |
4 |
0 |
0 |
0 |
next[1] = 0;
next[2] = 0;
很好理解,他们如果没有被匹配到,当然要去找第一个字符啊,第一个字符也匹配不了,当然就回家种地了
next[3] = 1
next[4] = 2
next[5] = 3
next[6] = 4
然而到第三位的时候,却不为0,不难看出,a[2] == a[0],这时候如果a[3]没有被匹配到,就可以访问a[1]看是否能匹配,4.5同理。
例如:
↓
A b a b a b a b c c c c
A b a b a b c c c c
↑
当匹配到如下字符时,发现不同,则回到↑所指位置再开始匹配,
换句话说,next[i] 就是在 i 前,产生了一个 next[i] 个字符的循环(前next[i]-1个字符与首next[i]-1个字符相匹配)
当解决next后,KMP就很简单了
i = 0 , j = 0
匹配串与被匹配串进行匹配,字符相同时
i++, j++;
当字符串不同时
i 不变(因为没有匹配上),j回到next[j](匹配串中的循环部分)
当 j = -1 时
i++,j=0 (从下一个字符开始,重新匹配)
KMP 不用像BF算法那样回溯,因为next数组处理了循环部分
不好理解的话,手动模拟一下样例
a a a b a a a b a a a a
a a a a
手模总是有助于理解的
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int Next[100];
void get_next(char *a)
{
int k = -1;
int j = 0;
Next[j] = k;
while(a[j] != '\0') {
if(k == -1 || a[j] == a[k]) {
k++;j++;
Next[j] = k;
}else k = Next[k];
}
}
int KMP(char S[],char T[])
{ get_next(T); int i=0;
int j=0;
while(S[i]!='\0' && T[j]!='\0'){
if(j == -1 || S[i] == T[j]){
i++;
j++;
}
else j = Next[j];
}
if(T[j]!='\0') return -1;
else return i-j+1;
} int main()
{
char a[100],b[100];
cin>>a>>b;
get_next(b); cout<<KMP(a,b)<<endl;
}
KMP 算法详解的更多相关文章
- kmp算法详解
转自:http://blog.csdn.net/ddupd/article/details/19899263 KMP算法详解 KMP算法简介: KMP算法是一种高效的字符串匹配算法,关于字符串匹配最简 ...
- [转] KMP算法详解
转载自:http://www.matrix67.com/blog/archives/115 KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的K ...
- KMP算法详解(转自中学生OI写的。。ORZ!)
KMP算法详解 如果机房马上要关门了,或者你急着要和MM约会,请直接跳到第六个自然段. 我们这里说的KMP不是拿来放电影的(虽然我很喜欢这个软件),而是一种算法.KMP算法是拿来处理字符串匹配的.换句 ...
- 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串
1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...
- 数据结构4.3_字符串模式匹配——KMP算法详解
next数组表示字符串前后缀匹配的最大长度.是KMP算法的精髓所在.可以起到决定模式字符串右移多少长度以达到跳跃式匹配的高效模式. 以下是对next数组的解释: 如何求next数组: 相关链接:按顺序 ...
- KMP算法详解&&P3375 【模板】KMP字符串匹配题解
KMP算法详解: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt(雾)提出的. 对于字符串匹配问题(such as 问你在abababb中有多少个 ...
- 字符串匹配KMP算法详解
1. 引言 以前看过很多次KMP算法,一直觉得很有用,但都没有搞明白,一方面是网上很少有比较详细的通俗易懂的讲解,另一方面也怪自己没有沉下心来研究.最近在leetcode上又遇见字符串匹配的题目,以此 ...
- KMP算法详解-彻底清楚了(转载+部分原创)
引言 KMP算法指的是字符串模式匹配算法,问题是:在主串T中找到第一次出现完整子串P时的起始位置.该算法是三位大牛:D.E.Knuth.J.H.Morris和V.R.Pratt同时发现的,以其名字首字 ...
- KMP算法详解 --- 彻头彻尾理解KMP算法
前言 之前对kmp算法虽然了解它的原理,即求出P0···Pi的最大相同前后缀长度k. 但是问题在于如何求出这个最大前后缀长度呢? 我觉得网上很多帖子都说的不是很清楚,总感觉没有把那层纸戳破, 后来翻看 ...
- 字符串匹配的KMP算法详解及C#实现
字符串匹配是计算机的基本任务之一. 举例来说,有一个字符串"BBC ABCDAB ABCDABCDABDE",我想知道,里面是否包含另一个字符串"ABCDABD" ...
随机推荐
- 机器学习算法中的偏差-方差权衡(Bias-Variance Tradeoff)
简单的以下面曲线拟合例子来讲: 直线拟合后,相比原来的点偏差最大,最后一个图完全拟合了数据点偏差最小:但是拿第一个直线模型去预测未知数据,可能会相比最后一个模型更准确,因为最后一个模型过拟合了,即第一 ...
- UVA 12293 - Box Game(博弈)
UVA 12293 - Box Game 题目链接 题意:两个盒子,一開始一个盒子有n个球.一个仅仅有1个球,每次把球少的盒子中球消掉,把多的拿一些球给这个盒子.最后不能操作的输(球不能少于1个),A ...
- 【Java】MyBatis与Spring框架整合(二)
本文讲解 Spring 注入映射器及事务功能的实现. 注入映射器实现 MyBatis 可以使用 SqlSession 的 getMapper ( Class<T> type ) 方法,根据 ...
- excel随机函数
=D7+RAND()*(8000-4250) 含义: 1.在D7数值的基础上,随机加一个数值,该数值的随机范围为4250——8000. 2.注意8000和4250要反着写
- 阿里云centos7.x 打开80端口(转)
本文转自:https://blog.csdn.net/tengqingyong/article/details/82805053 一 :阿里云centos7.x用iptables打开80端口 1.安装 ...
- 使用 LaTeX 画图系列
可以使用TikZ,用TikZ绘制出来的图形效果非常好,原生支持所有LaTeX语法. 使用 LaTeX 画柱状图/条形图参考:Guide to draw charts (basic, pie, bar) ...
- TLS/HTTPS 证书生成与验证
最近在研究基于ssl的传输加密,涉及到了key和证书相关的话题,走了不少弯路,现在总结一下做个备忘 科普:TLS.SSL.HTTPS以及证书 不少人可能听过其中的超过3个名词,但它们究竟有什么关联呢? ...
- MySql按周,按月,按日分组统计数据
知识关键词:DATE_FORMAT select DATE_FORMAT(create_time,'%Y%u') weeks,count(caseid) count from tc_case grou ...
- 【IOS】java 与oc之间的比较
Cocoa是什么,Cocoa是使用OC语言编写的工具包,里面有大量的类库.结构体,其实就相当于java中的标准API.C++中的标准库.OC中没有命名空间的概念,所以使用加前缀来防止命名冲突,因此你会 ...
- Gtk-WARNING**:无法在模块路径中找到主题引擎:“pixmap”的解决
Gtk-WARNING**:无法在模块路径中找到主题引擎:“pixmap”的解决 解决以上问题, 只需要安装 gnome-themes-standard 即可 如果终端中提示: (gvim:23 ...