在计算机科学中,Knuth-Morris-Pratt字符串查找算法(简称为KMP算法)可在一个主文本字符串S内查找一个模式串P的出现位置。此算法通过运用对这个模式串在不匹配时本身就包含足够的信息来确定下一个匹配将在哪里开始的发现,从而避免重新检查先前匹配的字符。

今天写完kmp的题, 发现又想不通了, 这个next数组实在是太绕了, 去跑步的路上不禁一直在想, 终于恍然大悟了! 感觉十分有必要写一篇解释, 用自己的话说说kmp以及这个next. 一方面加深一下印象, 另一方面希望给偶然看到的人一点点启发 (

简介

首先, 如果我们用传统的方式来匹配这个字符串, 会得到如下的过程:

如果用KMP算法, 将减少无用的挪动 :

这么看可能还看不出什么, 如果我们稍微变化一下就可以看到KMP算法的巨大优势 :

对于上图这种匹配, 普通的暴力算法将远远落后于kmp

kmp工作机制

如果你不知道"前后缀" 也许以下的图能更好的帮助理解

上图来源于这里

匹配过程

为什么是刚好跳转到next[i]

比如上面这个图中, 接下来我们会将失配位置移动到P[2]也就是A的地方(右移两下), 如果我们少移, 是不可能匹配的, 不然的话公共前后缀长度会比当前的值大

next数组的编程求法

重点 : 弄明白j回溯的原理

建议对照代码观看 :

int i = 0, j = -1;
while(i < s.size()) {
if(s[i] == s[j] || j==-1) {
i++;
j++;
next.push_back(j);
}
else {
j = next[j]; // 如果s[i]!=s[j]说明匹配失败, 回到上一级公共前后缀处
}
}

我们列出两个相邻的指针i和j, 初始指在数组前和0号元素的位置

接下来我列出从0开始求出next数组的图示

这里再附上两个写的不错的链接

http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html

https://www.bilibili.com/video/BV1Px411z7Yo?t=1068


好累啊

图解KMP以及next数组的求法的更多相关文章

  1. 转载-KMP算法前缀数组优雅实现

    转自:http://www.cnblogs.com/10jschen/archive/2012/08/21/2648451.html 我们在一个母字符串中查找一个子字符串有很多方法.KMP是一种最常见 ...

  2. 求最长公共前缀和后缀—基于KMP的next数组

    KMP算法最主要的就是计算next[]算法,但是我们知道next[]求的是当前字符串之前的子字符串的最大前后缀数,但是有的时候我们需要比较字符串中前后缀最大数,比如 LeetCode的shortest ...

  3. 06-01 Java 二维数组格式、二维数组内存图解、二维数组操作

    二维数组格式1 /* 二维数组:就是元素为一维数组的一个数组. 格式1: 数据类型[][] 数组名 = new 数据类型[m][n]; m:表示这个二维数组有多少个一维数组. n:表示每一个一维数组的 ...

  4. 【bzoj2384】[Ceoi2011]Match 特殊匹配条件的KMP+树状数组

    题目描述 给出两个长度分别为n.m的序列A.B,求出B的所有长度为n的连续子序列(子串),满足:序列中第i小的数在序列的Ai位置. 输入 第一行包含两个整数n, m (2≤n≤m≤1000000).  ...

  5. HDU - 4763 Theme Section (KMP的next数组的应用)

    给定一个字符串,求出一个前缀A,使得字符串的构成可以表示成ABABA的形式(B可以为空串). 输出这个前缀的最大长度. KMP算法Next数组的使用. 枚举中间的每个位置,可以根据Next数组求出这个 ...

  6. POJ 2752 KMP中next数组的应用

    题意: 让你从小到大输出给的字符串中既是前缀又是后缀的子串的长度. 思路: 先要了解这个东西: KMP中next数组表示的含义:记录着字符串匹配过程中失配情况下可以向前多跳几个字符,它描述的也是子串的 ...

  7. KMP(next数组的更新理解)Codeforces Round #578 (Div. 2)--Compress Words

    题目链接:https://codeforc.es/contest/1200/problem/E 题意: 有n串字符串,让你连起来:sample please ease in out   ---> ...

  8. UVA 11475 Extend to Palindrome (kmp || manacher || 后缀数组)

    题目链接:点击打开链接 题意:给你一个串,让你在串后面添加尽可能少的字符使得这个串变成回文串. 思路:这题可以kmp,manacher,后缀数组三种方法都可以做,kmp和manacher效率较高,时间 ...

  9. KMP中next数组的理解

    next数组是KMP的核心,但对于next数组我们总是有时候感觉明白了,但有时候又感觉没明白,现在我就说下我自己对KMP中next数组的理解,首先next[i]上的数字的意义,next[i]表示的是当 ...

随机推荐

  1. Java的集合(一)

    转载:https://blog.csdn.net/hacker_zhidian/article/details/80590428 Java集合概况就三个:List.set和map list(Array ...

  2. 201771010128王玉兰《面向对象程序设计(Java)》第八周学习总结

    第一部分:理论知识部分总结 (1)接口:接口不是类,而是对类胡一组需求描述,由常量肯一组抽象方法组成. a:接口中不包括变量和有具体实现的方法 b:只要类实现了接口,则该类要遵从接口描述的统 一格式进 ...

  3. PHP的图像函数

    imagecreate() 和 imagecreatetruecolor() 函数用于创建一幅空白图像. imagedestroy() 函数用于销毁图像资源. imagecreate() 如果我们要对 ...

  4. 当.Net成为大厂门槛代码小白该何去何从?

    掌握.Net已成为进入大厂的通行牌.越来越多的互联网软件公司开始使用.Net Core,根据去年数据显示腾讯.网易.顺丰.携程.中通.申通.同程艺龙.微医.233网校.问卷星.金蝶等关键业务已经在往. ...

  5. C#常见异常

    SystemException 其他用户可处理的异常的基本类 ArgumentException 方法的参数是非法的 ArgumentNullException 一个空参数传递给方法,该方法不能接受该 ...

  6. zookeeper安装部署步骤

    安装步骤 本安装教程,采用zookeeper 3.6.1 装java 下载zk包,分发到各个机器 确定或创建一个zookeeper的数据存放路径,并在该路径下创建一个myid文件,其中设置当前zook ...

  7. Java基础语法--分支结构

    if-else 结构 if(条件表达式){ 执行代码块; } if(条件表达式){ 执行代码块; }else { 执行代码块; } if(条件表达式){ 执行代码块; }else if (条件表达式) ...

  8. 【java】关键字volatile

    volatile 1. 含义: volatile是JVM提供的轻量级的同步机制,具有三个特点:保证可见性.不保证原子性.禁止指令重排. 1.1 保证可见性 一个线程修改了共享变量并写回主内存,其他线程 ...

  9. String类练习

    1.模拟一个trim方法,去除字符串两端的空格 2.将一个字符串进行反转.将字符串中指定部分进行反转 3.获取一个字符串在另一个字符串中出现的次数 4.获取两个字符串中最大相同子串 5.对字符串中字符 ...

  10. 容器技术之Dockerfile (一)

    在前边的随笔中我们聊到了docker的基本命令,镜像,网络,存储卷以及基于现有容器制做docker镜像,相关随笔可参考https://www.cnblogs.com/qiuhom-1874/categ ...