kmp算法标准板子题

class Solution {
public:vector<int> getNext(string needle){vector<int> next(needle.length());int k = -1 ;int j = 0;next[0] = -1;while(j < needle.length()-1){if(k == -1 || needle[j] == needle[k])next[++j] = ++k;elsek = next[k];}return next;}int strStr(string haystack, string needle) {int m = haystack.length();int n = needle.length();if(n == 0) return 0;int i = 0, j = 0;vector<int> next = getNext(needle);while(i < m && j < n){if(j == -1 || haystack[i] == needle[j]){i++;j++;}elsej = next[j];}if(j == n)return i - j;elsereturn -1;}
};

在这里记录一下KMP算法的理解

1.KMP是什么

对于主串a搜素子串b的问题:

暴力搜索的复杂度为O(主串长度*模式串长度)

暴力搜索就是a[i] != b[j]时

j = 0;

i = i - j + 1;

这样做效率极低。

如果利用KMP来做,时间复杂度O(m+n)为线性复杂度,已经是最低的了

2.KMP为什么这么做

以下面这个图为例,KMP算法的核心在于,当最后一位C与D无法匹配时,这时候有个隐含信息,就是匹配串的前三位ABA已经和主串的对应三位ABA匹配过,可能留下了一些匹配信息

如果拿之前的暴力搜索来看,最后一位C与D无法匹配时,

j会重置为0,i会变为1

B与A不匹配,j重置,i变为2;

然后比较B与C

像j=0与i=1匹配不上再移位的这种操作耗费了大量时间,我们能不能直接跳到上面这张j=0与i=2的比较图呢?

答案是肯定的,KMP算法就是利用了这个特性,当模式串的某一位不再匹配时,对于模式串不用重新从0开始,而是让i不变,j之前的模式串与主串刚好匹配就行。这样就省略了暴力搜索中需要j归零的操作。

3.KMP具体怎么做:

难点在于得出当子字符串的某一位无法匹配时,j变为多少

其实稍微分析一下就能看出结果

1.模式串的第一位就与主串不匹配,这时候需要原字符串的指针右移,用j = -1来表示,主要程序遇到j=-1表示i需要右移了。

2.模式串的第二位不匹配,j需要归零

3.模式串的第j位不匹配(j>1),这个时候就用了下面的这个公式进行递推

    next[0] = -1;while(j < s.length()-1){if(k == -1 || s[j] == s[k])next[++j] = ++k;elsek = next[k];}

这个公式的具体解释可见https://www.cnblogs.com/yjiyjige/p/3263858.html

换句话说,如果前一位字符和前一位要跳转到的字符相同,那么后面这一位的跳转位置就是前一位的跳转位置+1;

好了,现在知道这个对我们找出每一位的跳转位置有什么用呢?

对于前一位字符和前一位要跳转到的字符相同的情况,可以直接利用下面的公式进行递推

if(k = next[j] && s[k] == s[j])next[j+1] = k + 1;

对于s[k]与s[j]不相等的情况,上面贴出来的这篇文章根本没讲清楚。

我们可以这样想,首先next[j+1]肯定不在C的后面,可以用反证法证明:

假如在C的后面,那么j+1的前面一定是ABAC.......ABAB,这个与之前的next[j] = k矛盾,因为最长的前缀是ABA而不是ABAC......ABA,所以,next[j+1]可能的位置一定在C的前面

然后,这时候就是模式串ABAC与被匹配串ABAB....的最后一位冲突了而需要移位寻找BAB,AB或B的情况,所以

k = next[k]

5.关于为什么KMP算法不好理解的个人感受

KMP算法其实经历了好几个难点,只不过很多地方没把这些难点讲清楚。

暴力搜索的优化(难点1)

匹配失败后指针所移动到的位置的计算(难点2)

s[k]与s[j]不相等时next[++j]的计算(难点3)

leetcode28. Implement strStr() (以及个人对KMP算法理解)相关推荐

  1. KMP算法理解(转)

    (作者matrix67) KMP算法是拿来处理字符串匹配的.换句话说,给你两个字符串,你需要回答,B串是否是A串的子串(A串是否包含B串).比如,字符串A="I'm matrix67&quo ...

  2. KMP算法理解(参考BILIBILI正月点灯笼)

    前言 KMP算法最近看了很多的博客和视频始终没有清楚理解NEXT数组的构建,在B站看到正月点灯笼大神的视频,里面提出的前缀表对我有很大启发,今天来记录分享一下. BILIBILI 正月点灯笼 定义 s ...

  3. KMP算法理解(超简洁-易懂代码)

    文章目录 KMP算法 1. 暴力做法是怎么做的 1.1 时间复杂度: O(n^2) 2. 怎么去优化它 2.1 一般情况: 2.2 原理: 2.3 匹配过程 2.4 kmp 匹配的实现代码 2.5 n ...

  4. leetcode28 Implement strStr() 在字符串中寻找目标字符串

    题目要求: 在子字符串中寻找目标字符串,并返回该字符串第一次出现时的下标 在尝试的写了一提中等难度的题目后,又一次回到简单难度的题寻找温暖T-T 思路一 在原字符串中中寻找目标字符串首字母的下标,并提 ...

  5. leetcode28.实现strStr()--简单词学KPM算法

    class Solution {public int strStr(String haystack, String needle) {if(needle.isEmpty()) return 0;int ...

  6. 数据结构与算法之美笔记——基础篇(下):图、字符串匹配算法(BF 算法和 RK 算法、BM 算法和 KMP 算法 、Trie 树和 AC 自动机)

    图 如何存储微博.微信等社交网络中的好友关系?图.实际上,涉及图的算法有很多,也非常复杂,比如图的搜索.最短路径.最小生成树.二分图等等.我们今天聚焦在图存储这一方面,后面会分好几节来依次讲解图相关的 ...

  7. 【数据结构】详解KMP算法

    字符串匹配算法:简单来说就是给你一个主串和一个子串,让你查找子串在主串中的位置,找到返回下标. 常见的两种算法:BF算法.KMP算法 这两种算法是怎样的思路呢,我们接着往下看: 目录 BF算法(暴力算 ...

  8. 【To Do】LeetCode 28. Implement strStr() 和KMP算法

    LeetCode 28. Implement strStr() Solution1:我的答案 有投机取巧之嫌啊~ 注意string中的查找函数在查找时 参考网址:https://www.cnblogs ...

  9. leetcode28. 实现 strStr(KMP详解)

    一:题目 二:思路 三:上码 // class Solution {// public: // int strStr(string haystack, string needle) {// if (n ...

最新文章

  1. Android 替换TextView 里面指定的符号
  2. LPC1768基本输入输出GPIO使用
  3. WordCount案例
  4. 增强for循环之删除
  5. boost::boost::directed_graph用法的测试程序
  6. asp.net core 自定义 Content-Type
  7. python 斐波那契数列 yield_Python中的yield到底是个什么鬼?
  8. iOS开发证书和配置文件的使用
  9. 老程序员为什么从不使用 Java 自带的序列化?
  10. 【数字基带信号】基于matlab数字基带信号波形仿真【含Matlab源码 988期】
  11. 计算机毕业论文答辩申请书,论文答辩申请书范文6篇
  12. Vivado2018.3手把手详细下载
  13. 代理模式和装饰者模式区别
  14. 2020年十大数字客户体验(CX)软件平台
  15. Win10 C盘清理的技巧,将C盘中除Windows外的所有系统文件夹移到C盘之外,节约大部分C盘空间
  16. iOS 卡顿原因及优化思路
  17. eclipse wifi 连接手机
  18. jQuery搜索高亮显示
  19. 物联网应用技术竞赛 ——数据库添加新用户映射
  20. 解决文件名是中文时的下载乱码问题

热门文章

  1. WINDOWS SERVER 2003从入门到精通之组策略应用
  2. 黑鹰ASP教程(全部)下载
  3. React脚手架搭建及目录结构介绍
  4. scrapy分布式去重组件源码及其实现过程
  5. openlayers之style符号化
  6. 配置文件总结(机房重构知识点总结)
  7. QQ 邮箱的换肤 bug
  8. InnoDB和MyISAM引擎的效率比较
  9. vector机器人 PHOTOS TAKEN BY VECTOR 由 VECTOR 拍摄的照片
  10. golang 执行命令 设置超时