做题思路 or 感想 :

就借由这道题来理解一下kmp算法吧

  1. kmp算法的操作过程我觉得有句话很合适 :KMP 算法永不回退 目标字符串 的指针 i,不走回头路(不会重复扫描 目标字符串),而是借助 next 数组中储存的信息把 模板字符串 移到正确的位置继续匹配

  2. 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

  3. 最后是利用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() 为例的更多相关文章

  1. KMP算法 --- 深入理解next数组

    在KMP算法中有个数组,叫做前缀数组,也有的叫next数组. 每一个子串有一个固定的next数组,它记录着字符串匹配过程中失配情况下可以向前多跳几个字符. 当然它描述的也是子串的对称程度,程度越高,值 ...

  2. KMP算法的理解

    ---恢复内容开始--- 在看数据结构的串的讲解的时候,讲到了KMP算法——一个经典的字符串匹配的算法,具体背景自行百度之,是一个很牛的图灵奖得主和他的学生提出的. 一开始看算法的时候很困惑,但是算法 ...

  3. 关于《数据结构》课本KMP算法的理解

    数据结构课上讲的KMP算法和我在ACM中学习的KMP算法是有区别的,这里我对课本上的KMP算法给出我的一些想法. 原理和之前的KMP是一样的https://www.cnblogs.com/wkfvaw ...

  4. 关于KMP算法的理解

    上次因为haipz组织的比赛中有道题必须用到KMP算法,因此赛后便了解了下它,在仔细拜读了孤~影神牛的文章之后有种茅塞顿开的感觉,再次ORZ. 附上链接http://www.cnblogs.com/y ...

  5. 我对KMP算法的理解

    KMP算法的核心在于失配回溯表——pnext,相比于通过逐个比较来匹配字符串的朴素算法,KMP通过对模式串的分析,可以做到比较指针在主串上不回溯,一直向前. 1. KMP如何实现不回溯? 对于主串 t ...

  6. KMP算法自我理解 和 模板

    字符串   abcd abc abcd abc 匹配串   cdabcd 匹配串的 next  0 0 0 0 1 2: 开始匹配 abcd abc abcd abc cd abc d a,d 匹配失 ...

  7. 第十一章 串 (c3)KMP算法:理解next[]表

  8. kmp算法初步理解

    123456789 abbdaxnds Next   01212 第三位看第二位b,第二位和第三位相同,都是b,所以第三位的next是第二位的next加1,即1+1=2 第四位看第三位b,第四位d与第 ...

  9. KMP算法中next函数的理解

    首先要感谢http://blog.csdn.net/v_july_v/article/details/7041827以及http://blog.chinaunix.net/uid-27164517-i ...

随机推荐

  1. 5. Java方法

    5.Java方法 1.何谓方法 Java方法是语句的集合,它们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合 方法包含于类或对象中 方法在程序中被创建,在其他地方被引用 设计方法的原则:方法 ...

  2. BM 学习笔记

    两个 BM 哟 1.Bostan-Mori 常系数其次线性递推. 实际上这个算法是用来计算 \([x^n]\frac {F(x)}{G(x)}\) 的... 我们考虑一个神奇的多项式:\(F(x)F( ...

  3. CF1385G口胡

    只能说很神秘??? 首先观察题面,假设给出的第一个序列为 \(a\),第二个序列为 \(b\).对于 \((a_i,b_i)\) 我们连一条边. 得到的是一个 \(n\) 个点 \(n\) 条边的不一 ...

  4. 使用Truffle 部署智能合约

    使用Truffle 部署智能合约 之前我们使用Geth,原生的以太坊Golang工具,分析了创世区块的参数内容,在本地创建了私有以太坊区块链,并使用两个账户进行了挖矿和转账操作,对以太坊有了基本了解. ...

  5. app自动化toast信息获取

    移动端测试比较常遇到toast类型的提示信息,那么对于这类信息我们要怎么获取呢,让我细细道来: 首先,获取toast信息要注意以下几点: 必须是Uiautomator2框架,设备配置参数中设置 &qu ...

  6. FrameScan CMS漏洞扫描

    工具简介 GithubL:https://github.com/qianxiao996/FrameScan FrameScan是一款python3编写的简易的cms漏洞检测框架,支持多种检测方式,支持 ...

  7. Java基础 (上)

    基础概念与常识 Java 语言有哪些特点? 简单易学: 面向对象(封装,继承,多态): 平台无关性( Java 虚拟机实现平台无关性): 支持多线程( C++ 语言没有内置的多线程机制,因此必须调用操 ...

  8. 安卓开发学习-app结构学习

    开发软件:Android Studio 全局分析 gradle与idea是AS自动生成的文件 buid是编译时生成的文件 gradle里面包含gradle wrapper配置文件 gitignore是 ...

  9. Spring 的 jdbcTemplate 操作

    1.Spring框架是一站式框架 (1)针对 JavaEE 三层,每一层都有解决技术 (2)在 dao 层,使用 jdbcTemplate 2.Spring对不同的持久化层的技术都进行了封装 (1)j ...

  10. 学习Tomcat(一)

    一.jdk和tomcat基础 1.web应用对比 apache: 两种方式运行php,一是用模块,二是用fastcgi nginx: 通过fastcgi处理动态请求,也可转发到tomcat 2.tom ...