▎前言

  这次要讲的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. windy数(数位dp)

    https://www.luogu.com.cn/blog/virus2017/shuweidp https://www.luogu.com.cn/problem/P2657 #include < ...

  2. 一文了解JDK12 13 14 GC调优秘籍-附PDF下载

    目录 简介 那些好用的VM参数 G1的变化 配置FlightRecorder RAM参数 JDK13中的ZGC RTM支持 总结 简介 想了解JDK12,13,14中的GC调优秘籍吗?想知道这三个版本 ...

  3. 郭神的关于git软件和http的文章

    https://blog.csdn.net/guolin_blog/article/details/17482095

  4. 解决智慧城市发展困扰:Web 3D 智慧环卫 GIS 系统

    前言 智慧环卫,依托物联网技术与移动互联网技术,对环卫管理所涉及到的人.车.物.事进行全过程实时管理,合理设计规划环卫管理模式,提升环卫作业质量,降低环卫运营成本,用数字评估和推动垃圾分类管理实效.智 ...

  5. Kubernetes中强制删除Pod、namespace

    Kubernetes中强制删除Pod.namespace 解决方法 可使用kubectl中的强制删除命令 # 删除POD kubectl delete pod PODNAME --force --gr ...

  6. pandas之时间数据

    1.时间戳Timestamp() 参数可以为各种形式的时间,Timestamp()会将其转换为时间. time1 = pd.Timestamp('2019/7/13') time2 = pd.Time ...

  7. 什么是Hexo博客

    Hexo 是一个基于nodejs 的静态博客网站生成器,作者是来自台湾的Tommy Chen. 特点: 不可思议的快速 ─ 只要一眨眼静态文件即生成完成 支持 Markdown 仅需一道指令即可部署到 ...

  8. Skill 脚本演示 ycFloatUpLayer.il

    https://www.cnblogs.com/yeungchie/ ycFloatUpLayer.il 将选中 instance 中的指定 lpp "上浮". 回到目录

  9. QT学习笔记(day01)

    QT中的对象树 一定程度上简化了内存回收机制:当创建的对象 指定的父亲是由QObject或者Object派生的类时候,这个对象被加载到对象树上,当窗口关闭掉时候,树上的对象也都会被释放掉 信号和槽 通 ...

  10. 【从零开始撸一个App】Dagger2

    Dagger2是一个IOC框架,一般用于Android平台,第一次接触的朋友,一定会被搞得晕头转向.它延续了Java平台Spring框架代码碎片化,注解满天飞的传统.尝试将各处代码片段串联起来,理清思 ...