自己对kmp算法的理解,借由 28. 实现 strStr() 为例
做题思路 or 感想 :
就借由这道题来理解一下kmp算法吧
kmp算法的操作过程我觉得有句话很合适 :KMP 算法永不回退
目标字符串的指针i,不走回头路(不会重复扫描目标字符串),而是借助next数组中储存的信息把模板字符串移到正确的位置继续匹配kmp算法的重要点是计算next数组
i的含义是指向后缀末尾位置的下标,j的含义是指向前缀末尾位置的下标和最大前后缀和!!!
next[i]的定义是i(包括i)之前的最长前后缀之和
对于for循环中为什么i要从1开始,因为i是后缀末尾,0是初始化的前缀末尾,如果要比较前后缀,则必须要是初始前缀末尾的正好后一位,这样子前后缀才能开始比较!
当前后缀所表示的字符不相等,则
while (j > 0 && s[j] != s[i]) {
j = next[j - 1];
}
上面是因为要找到一个和s[i]匹配的字符,或者直接降到第一个的 j = 0,所以要用
while来控制当前后缀所表示的字符相等时,则
if (s[i] == s[j]) {
j++; //这里我理解是因为j的含义是最长前后缀之和,而现在前后缀匹配了,所以前后缀之和长度要+1
}
最后的最后,无论匹配或不匹配,都要给
next[i]赋值,即是next[i] = j
最后是利用next数组来进行对目标字符串的匹配,这里carl哥没有详细讲,我就写点我自己的理解,有误是有误,但好歹是写给自己看的嘛,以后还可以改哈哈
在匹配时,i的含义是目标字符串的匹配位置,j的含义是模板字符串的匹配位置(我可太容易在含义概念上搞混了)
首先是匹配时的
for (int i = 0; i < 目标字符串大小; i++)和next数组构建时有不同,因为这里比较的是两个串,所以要从一开始的下标0匹配,而构建next数组时是对一个串的前后缀匹配,所以构建next数组时i是要从1开始初始化然后由
while (j > 0 && aim[i] != needle[j]) { //用的是while
j = next[j - 1]; //注意这里是看前一位的next数组来进行回退操作
}
来确定模板字符串的匹配位置
如果
aim[i] == needle[j]则匹配成功,则有j++使得匹配位置往前进一步
回到一开始的这道题,其实就是把上面的操作全部抄一遍就好了,二刷后对kmp算法的理解感觉比一刷的时候深刻了不少啊
class Solution {
public:
void getNext(const string& s, vector<int>& next) {
int j = 0;
next[0] = j;
for (int i = 1; i < s.size(); i++) {
while (j > 0 && s[i] != s[j]) {
j = next[j - 1];
}
if (s[j] == s[i]) {
j++;
}
next[i] = j;
}
}
int strStr(string haystack, string needle) {
if (needle.size() == 0)return 0;
vector<int> next(needle.size() + 1, 0);
getNext(needle, next);
int j = 0;
for (int i = 0; i < haystack.size(); i++) {
while (j > 0 && haystack[i] != needle[j]) {
j = next[j - 1];
}
if (haystack[i] == needle[j]) {
j++;
}
if (j == needle.size()) {
return i - needle.size() + 1;
}
}
return -1;
}
};
自己对kmp算法的理解,借由 28. 实现 strStr() 为例的更多相关文章
- KMP算法 --- 深入理解next数组
在KMP算法中有个数组,叫做前缀数组,也有的叫next数组. 每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符. 当然它描述的也是子串的对称程度,程度越高,值 ...
- KMP算法的理解
---恢复内容开始--- 在看数据结构的串的讲解的时候,讲到了KMP算法——一个经典的字符串匹配的算法,具体背景自行百度之,是一个很牛的图灵奖得主和他的学生提出的. 一开始看算法的时候很困惑,但是算法 ...
- 关于《数据结构》课本KMP算法的理解
数据结构课上讲的KMP算法和我在ACM中学习的KMP算法是有区别的,这里我对课本上的KMP算法给出我的一些想法. 原理和之前的KMP是一样的https://www.cnblogs.com/wkfvaw ...
- 关于KMP算法的理解
上次因为haipz组织的比赛中有道题必须用到KMP算法,因此赛后便了解了下它,在仔细拜读了孤~影神牛的文章之后有种茅塞顿开的感觉,再次ORZ. 附上链接http://www.cnblogs.com/y ...
- 我对KMP算法的理解
KMP算法的核心在于失配回溯表——pnext,相比于通过逐个比较来匹配字符串的朴素算法,KMP通过对模式串的分析,可以做到比较指针在主串上不回溯,一直向前. 1. KMP如何实现不回溯? 对于主串 t ...
- KMP算法自我理解 和 模板
字符串 abcd abc abcd abc 匹配串 cdabcd 匹配串的 next 0 0 0 0 1 2: 开始匹配 abcd abc abcd abc cd abc d a,d 匹配失 ...
- 第十一章 串 (c3)KMP算法:理解next[]表
- kmp算法初步理解
123456789 abbdaxnds Next 01212 第三位看第二位b,第二位和第三位相同,都是b,所以第三位的next是第二位的next加1,即1+1=2 第四位看第三位b,第四位d与第 ...
- KMP算法中next函数的理解
首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...
随机推荐
- 一比一还原axios源码(零)—— 概要
从vue2版本开始,vue-resource就不再被vue所维护和支持,官方也推荐使用axios,所以,从我使用axios至今,差不多有四五年了,这四五年的时间只能算是熟练应用,很多内部的实现和原理不 ...
- Dapr云原生应用开发系列7:工作流集成
题记:这篇介绍一个很有意思的东西,Dapr和Logic Apps这样的工作流引擎集成. Dapr工作流 在1年多前,Dapr的孵化团队搞了一个很有意思的东西:把Dapr和Logic Apps集成起来, ...
- 当.Net撞上BI可视化,这3种“套路”你必须知道
最近葡萄在做技术支持,又遇到了客户给我们出的新问题. 事情是这样的. 这次客户使用的是.Net项目,直接做BI大屏过于复杂,所以想直接集成使用BI数据可视化分析大屏. 所以,这次我们就从--Wyn出发 ...
- Linux开机自启应用&开机执行脚本&监听端口应用挂掉了执行启动脚本
linux开机自启 背景 目前要部署一个spring boot框架的jar包,实现开机启动项目或者应用挂掉了 执行启动脚本 在root目录下有一个启动项目的脚本: app_start.sh app_s ...
- 聊聊视频中的编解码器,你所不知道的h264、h265、vp8、vp9和av1编解码库
你知道FFmpeg吗?了解过h264/h265/vp8/vp9编解码库吗? 我们日常生活中使用最广泛的五种视频编码:H264(AVC).H265(HEVC).vp8.vp9.av1都分别是什么?由哪些 ...
- CF1483F口胡
<线 性 做 法> 首先我们对所有串建立 ACAM,不难发现对于一个 \(i\),可能的 \(j\) 一定是 \(i\) 所有后缀节点在 fail 树上第一个被打标记的祖先. 但是这些祖先 ...
- LGP4451题解
题意明确,不再阐述( 首先,众所周知的是 斐波那契数列 的生成函数是 \(F(x)=\frac x {1-x-x^2}\) 那么答案就是 \(\sum_{i=0} F^i(x) = \frac 1 { ...
- selenium&火狐驱动安装及兼容性处理
1.selenium安装 安装:pip install selenium==3.7.0 卸载: pip uninstall selenium 查看版本号:pip show selenium 2.火 ...
- FrameScan-GUI CMS漏洞扫描
工具简介 FrameScan-GUI是一款python3和Pyqt编写的具有图形化界面的cms漏洞检测框架,是FrameScan的加强版.支持多种检测方式,支持大多数CMS,可以自定义CMS类型及自行 ...
- 三极管与MOS管主要参数差别及驱动电路基极(栅极)串联电阻选取原则
三极管与MOS管都常在电路中被当做开关使用,比较起来: 1. 三极管集电极电流IC (一般为mA级别),远小于MOS管ID(一般为A级别),因此MOS管多用在大电流电路中,如电机驱动 2. 三极管耗散 ...