▎前言

  这次要讲的HMP算法KMP算法很简单,是用于处理字符串的,之前一直以为很难,其实也不过如此(说白了就是优化一下暴力)。

▎处理的问题

  通常处理的问题是这样的:给定两个字符串s1和s2,其中s1是文本串,s2是匹配串,求s2在s1中出现的位置。

  举个例子:(方便起见,下标从1开始)比如说s1是AABAAC,s2是BA,那么s2在s1的第3个位置处出现。

▎暴力求解

  如何使用暴力求解这道题呢?我们只要分别暴力遍历两个字符串,然后分别比对当前字符,如果相等就继续比下去,如果不相等,那么s1回溯回没有执行这一次比对的位置,s2遍历的位置归零。

  代码如下,详见注释:

 #include<iostream>
using namespace std;
string s1,s2;int i=,j=;
int main()
{
cin>>s1;cin>>s2;
int len1=s1.length();int len2=s2.length();
while(i<len1&&j<len2)
{
if(s1[i]==s2[j])
{
i++;
j++;
}
else
{
i=i-j+;
j=;
}
}
if(j==len2) cout<<i-j;
else cout<<"No answer";
return ;
}

▎KMP算法

☞『定义』

  KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt提出的,因此人们称它为克努特莫里斯普拉特操作(简称KMP算法)。KMP算法的核心是利用匹配失败后的信息,尽量减少模式串与主串的匹配次数以达到快速匹配的目的。具体实现就是通过一个next()函数实现,函数本身包含了模式串的局部匹配信息。KMP算法的时间复杂度O(m+n)。(copy自百度)

  说白了就是把暴力求解的过程优化一下。

☞『算法核心』

  仔细思考一下,为什么暴力求解效率不高呢?

  这个问题很好回答,因为我们直接比对失败后就抛弃了,因此没有利用到这些匹配失败的东西,如果我们能够合理的利用,在失败的基础上继续比对,那么就可以优化了。

  KMP算法不同于暴力的地方就在于把比对失败的当前遍历的字符串准确找到一个之前信息一样的字符串,继续比对。  

  比如说s1是AABAAC,s2是AB,在遍历到AA时发现不同,那么之前相同的是A,那么跳转到下一个A所在的位置继续比对,也就是跳到了第二个A的位置,发现相同,那么就找到了。

  其余的与暴力相同,只不过跳转就成为了一大难点。

  那么我们现在来考虑如何跳转,我们可以使用一个数组(next)来存储当前信息相同的位置,那么我们可以定义两个指针(不是语法中的指针,此指针非彼指针),初始化一个在0,一个在-1。

  如果一个在-1(还没有开始比对,或者跳转到了这里)或者当前字符相同,那么就继续比对。否则就将其中一个跳转。

  总而言之看代码吧。

☞『代码如下』

 #include<iostream>
#include<cstring>
using namespace std;
char s1[],s2[];int i=-,j=,next[];
int main()
{
cin>>s1;cin>>s2;
int len1=strlen(s1);int len2=strlen(s2);//输入字符串
next[]=-;//初始化
while(j<len2-)
{
if(i==-||s2[i]==s2[j])//-1可能是初始状态的,也可能是跳过来的
{
i++;
j++;
next[j]=i;//顺便记录下来
}
else i=next[i];//跳到另一个信息一样的地方
}
i=;j=;
while(i<len1&&j<len2)//常规操作
{
if(j==-||s1[i]==s2[j])
{
i++;
j++;
}
else j=next[j];//跳转
}
if(j==len2) cout<<i-j;
else cout<<"No answer";
return ;
}

【算法•日更•第三十一期】KMP算法的更多相关文章

  1. 【算法•日更•第三十期】区间动态规划:洛谷P4170 [CQOI2007]涂色题解

    废话不多说,直接上题:  P4170 [CQOI2007]涂色 题目描述 假设你有一条长度为5的木版,初始时没有涂过任何颜色.你希望把它的5个单位长度分别涂上红.绿.蓝.绿.红色,用一个长度为5的字符 ...

  2. 【算法•日更•第三十九期】迭代加深搜索:洛谷SP7579 YOKOF - Power Calculus 题解

    废话不多说,直接上题: SP7579 YOKOF - Power Calculus 题意翻译 (略过没有营养的题干) 题目大意: 给出正整数n,若只能使用乘法或除法,输出使x经过运算(自己乘或除自己, ...

  3. 【算法•日更•第三十五期】FF算法优化:EK算法

    ▎写在前面 FF算法传送门 之前我们已经学过了FF算法(全称Ford-Fulkerson算法)来找最大流,但是这种算法仍有诸多不对的地方. 其实这种算法存在着严重的效率的问题,请看下面的图: 以这个图 ...

  4. 【算法•日更•第三十二期】教你用出windows体验的Linux

    ▎前言 小编昨天闲的不行,就装了一个linux系统,linux的发行版很多,小编认为ubuntu很好用,于是就在使用ubuntu. 没错,我现在就在使用ubuntu来写博客. 刚才还装了一个QQ,不过 ...

  5. 【算法•日更•第五十期】二分图(km算法)

    ▎前言 戳开这个链接看看,惊不惊喜,意不意外?传送门. 没想到我的博客竟然被别人据为己有了,还没办法投诉. 这年头写个博客太难了~~~ 之前小编写过了二分图的一些基础知识和匈牙利算法,今天来讲一讲km ...

  6. 【算法•日更•第五十四期】知识扫盲:什么是operator?

    ▎前言 这个东西和迭代器长的很像,但是比迭代器常见的多. 今天就来浅谈operator. ▎定义 operator是C#.C++和pascal的关键字,它和运算符一起使用,表示一个运算符函数,理解时应 ...

  7. 【算法•日更•第三十七期】A*寻路算法

    ▎写在前面 这是一种搜索算法,小编以前总是念成A乘寻路算法,没想到一直念错. 请大家都念成A星寻路算法,不要像小编一样丢人了. ▎A*寻路算法 ☞『引入』 相信大家都或多或少的玩过一些游戏吧,那么游戏 ...

  8. 【算法•日更•第四十二期】离散傅里叶变换(DFT)

    ▎前言 小编相当的菜,这篇博客难度稍高,所以有些可能不会带有证明,博客中更多的是定义. 我们将要学到的东西: 复数 暴力多项式乘法 DFT 当然,小编之前就已经写过一篇博客了,主要讲的就是基础多项式, ...

  9. 【算法•日更•第四十三期】QQ for linux

    废话不多说,直接看一张图: 没错,这是QQ,但是这有什么稀奇的?但是在Linux上使用QQ就很稀奇了. 众所周知,腾讯早就已经对Linux下的QQ和微信停止了服务,即便是网页版也不能用,通信这一直是小 ...

随机推荐

  1. redis pipelined 示例

    redis 常用的数据类型 有序集合(sort set).无序集合 (set),hashMap redis pipelined 示例 List<Object> list = jedisTe ...

  2. Zuul原理

    @EnableZuulProxy和@EnableZuulServer @EnableZuulProxy和@EnableZuulServer通过实例化不同的Marker,走不同的AutoConfigur ...

  3. hibearnate的一级缓存和二级缓存的功能

    首先要明白缓存是干什么的,缓存就是要将一些经常使用的数据缓存到内存或者各种储存介质中,当再次使用时可以不用去数据库中查询,减少与数据库的交互,提高性能.再说明一级与二级缓存的作用:一级缓存是Sessi ...

  4. Python语言及其应用|PDF高清完整版免费下载|百度云盘|Python

    百度云盘:Python语言及其应用PDF高清完整版免费下载 提取码:6or6 内容简介 本书介绍Python 语言的基础知识及其在各个领域的具体应用,基于最新版本3.x.书中首先介绍了Python 语 ...

  5. 互联网找的e是无理数的初等证明

    e的两种计算方式 \(e=lim_{n \to \infty}(1+\frac{1}{n})^n\) \(e=\sum_{n=0}^{+\infty}\frac{1}{n!}\) \(即,e=\fra ...

  6. 小书MybatisPlus第9篇-常用字段默认值自动填充

    本文为Mybatis Plus系列文章的第9篇,前8篇访问地址如下: 小书MybatisPlus第1篇-整合SpringBoot快速开始增删改查 小书MybatisPlus第2篇-条件构造器的应用及总 ...

  7. shell变量子串

    表达式 说明 ${parameter} 返回变量$parameter的内容 ${#parameter} 返回变量$parameter内容的长度(按字符),也适用于特殊变量 ${parameter:of ...

  8. 动态规划入门(dp)

    dp的基本思想,是把大问题转化成一个个小问题,然后递归解决. 所以本质思想的话还是递归. dp最重要的是要找到状态转移方程,也就是把大问题化解的过程. 举个例子 一个数字金字塔 在上面的数字三角形中寻 ...

  9. 编程小白的第一本python入门书电子版|百度网盘分享无偿获取|评分超高的python教材

    点此进入网盘下载提取码:cr74 为了能让更多的编程小白轻松地入门编程,把高效学习法结合 Python 中的核心知识,写成了这本书.随意翻上几页,你就会发现这本书和其他编程书的不同,其中有大量的视觉化 ...

  10. Radiobutton基础语法

    .Radiobutton(root 主窗口,text 文本内容,value 值(可以通过set 和 get 获取到的值),variable 变量修改原来的StringVar) self.radio_m ...