一、概述

KMP算法是一种字符串匹配算法,比如现有字符串

T:ABCDABCDABCDCABCDABCDE,

P:ABCDABCDE

P字符串对应的next值:[0,0,0,0,1,2,3,4,0]

二、匹配过程

判断T字符串是否包含P字符串?下面看一下KMP的比较过程:

三、next数组计算过程

先了解一下字符串的前后缀(具体来说是前后缀即 前缀不包含最后一个字符;后缀不包含第一个字符)

字符串

真前缀

真后缀

真前、后缀中相

同的字符串

真前、后缀中

最大相同串

真前、后缀中最

大相同串字符数

abc

a,ab

bc,c

0

aaa

a,aa

aa,a

a,aa

aa

2

aba

a,ab

ba,a

a

a

1

abab

a,ab,aba

bab,ab,b

ab

ab

2

ababab

a,ab,aba,abab,ababa

babab,abab,bab,ab,b

ab,abab

abab

4

那“ABCDABCDE”字符串的最大真前后缀的计算过程如下:

子串

真前缀字符串

真后缀字符串

真前、后缀中最

大相同串字符

真前、后缀中最

大相同串字符数

A

0

AB

A

B

0

ABC

AB、A

BC、C

0

ABCD

ABC、AB、A

BCD、CD、D

0

ABCDA

ABCD、ABC、AB、A

BCDA、CDA、DA、A

A=A

1

ABCDAB

ABCDA、ABCD、ABC、AB、A

BCDAB、CDAB、DAB、AB、B

AB=AB

2

ABCDABC

ABCDAB、ABCDA、ABCD、

ABC、AB、A

BCDABC、CDABC、DABC、

ABC、BC、C

ABC=ABC

3

ABCDABCD

ABCDABC、ABCDAB、ABCDA、

ABCD、ABC、AB、A

BCDABCD、CDABCD、DABCD、

ABCD、BCD、CD、D

ABCD=ABCD

4

ABCDABCDE   

ABCDABCD、ABCDABC、ABCDAB、

ABCDA、ABCD、ABC、AB、A

BCDABCDE、CDABCDE、DABCDE、

ABCDE、BCDE、CDE、DE、E

0

 

由上表得出最大真前后缀的结果为:{0,0,0,0,1,2,3,4,0}

接下来需要把这最大真前后缀值转换为next值

索引

0

1

2

3

4

5

6

7

8

字符串

A

B

C

D

A

B

C

D

E

最大真前后缀数

0

0

0

0

1

2

3

4

0

Next

-1

0

0

0

0

1

2

3

4

通过上面的表格可以发现就是把最大真前后缀的值整体向后以后一位,所以next值为:{-1,0,0,0,0,1,2,3,4},计算出这个next数组之后,接下来在匹配的过程中就可以使用了。

注意:有的人感觉使用最大真前后缀也可以作为next值,这是可以作为的,只是在计算最大真前后缀的逻辑代码相对复杂一点点,并且在匹配使用的时候也会复杂一点点

四、实现代码

计算next值的代码

 1 public static int[] computeNext(char[] chs) {
2 int i = 0;
3 int j = -1;
4 int[] next = new int[chs.length];
5 next[i] = j;
6 while (i < chs.length - 1) {
7 if (j == -1 || chs[i] == chs[j]) {
8 i++;
9 j++;
10 next[i] = j;
11 } else {
12 j = next[j];
13 }
14 }
15 return next;
16 }

计算最大真前后缀的代码:

1 public static int[] getPreSuffix(char[] cs) {
2 int j = 0;
3 int i = 1;
4 int len = cs.length;
5 int[] preSuffix = new int[len];
6 preSuffix[1] = 0;
7 while (i < len) {
8 if (j == 0) {
9 if (cs[j] == cs[i]) {
10 preSuffix[i] = j + 1;
11 j++;
12 i++;
13 } else {
14 i++;
15 }
16 } else {
17 if (cs[j] == cs[i]) {
18 preSuffix[i] = j + 1;
19 j++;
20 i++;
21 } else {
22 j = preSuffix[j - 1];
23 }
24 }
25 }
26 return preSuffix;
27 }

大家有什么疑问、建议欢迎留言、讨论!

来去学习之---KMP算法--next计算过程的更多相关文章

  1. 学习笔记-KMP算法

    按照学习计划和TimeMachine学长的推荐,学习了一下KMP算法. 昨晚晚自习下课前粗略的看了看,发现根本理解不了高端的next数组啊有木有,不过好在在今天系统的学习了之后感觉是有很大提升的了,起 ...

  2. [一本通学习笔记] KMP算法

    KMP算法 对于串s[1..n],我们定义fail[i]表示以串s[1..i]的最长公共真前后缀. 我们首先考虑对于模式串p,如何计算出它的fail数组.定义fail[0]=-1. 根据“真前后缀”的 ...

  3. KMP算法之查找模式串在源串中出现的次数

    问题描述: 给定两个字符串T, P.查找字符串P在字符串T中出现的次数. 解决方法: 典型的KMP算法的题目,在此使用的KMP算法为算法导论上介绍的算法.下一篇文章将详细介绍KMP算法的计算过程. 题 ...

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

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

  5. KMP算法 Next数组详解

    题面 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百 ...

  6. 字符串匹配的 KMP算法

    一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...

  7. 数据结构4_java---顺序串,字符串匹配算法(BF算法,KMP算法)

    1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 ...

  8. 程序员的算法课(11)-KMP算法

    版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...

  9. KMP算法,看这篇就够了!

    普通的模式匹配算法(BF算法) 子串的定位操作通常称为模式匹配算法 假设有一个需求,需要我们从串"a b a b c a b c a c b a b"中,寻找内容为"a ...

随机推荐

  1. 玩转Django2.0---Django笔记建站基础四(视图)

    第四章 视图 4.1 探究视图 一.视图说明 视图(View)是Django的MTV架构模式的V部分,主要负责处理用户请求和生成相应的相应部分,然后在页面或其它类型文档中显示.也可以理解为视图是MVC ...

  2. FastDF step by step

    step one 肯定是安装一个FastDF服务了 step two FasDFS配置节点 step third 码代码

  3. 团队项目-Beta冲刺1(七个小矮人)

    团队项目-Beta冲刺1(七个小矮人) 一.格式描述 这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/GeographicInformationScien ...

  4. CentOS7安装MySQL、Tomcat和GitBlit记录

    一.安装MySQL 1.安装这个发布包 yum localinstall mysql-community-release-el6-5.noarch.rpm 可以通过下面的命令来确认这个仓库被成功添加: ...

  5. java 排序算法分析

    一.冒泡排序(时间复杂度O(N^2)) public int[] bubbling(int[] arr){ ) return arr; ; i--){ 1 ; j < i-; j ++){ 2 ...

  6. SQLException:The server time zone

    报错信息如下: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represen ...

  7. 类加载之 <clinit>() 和 <init>()

    前序文章:深入理解Java类加载 <clinit>() 与 <init>() 区别 一.<clinit>() Java 类加载的初始化过程中,编译器按语句在源文件中 ...

  8. Perl Tk在IC设计中的应用、Windows、Linux平台下的安装-各种错误的摸索解决

    本文转自:自己的微信公众号<集成电路设计及EDA教程> <Perl Tk在IC设计中的应用.Windows.Linux平台下的安装-各种错误的摸索解决> Perl在IC设计中有 ...

  9. jQuery初学者笔记 一

    jQuery初学者笔记 一 Mirror王宇阳 by jQuery语法 jQuery语法是通过选取HTML元素,并对选取的元素进行操作 基础语法: 所有jQuery语句用"$"符号 ...

  10. Go操作MongoDB

    mongoDB是目前比较流行的一个基于分布式文件存储的数据库,它是一个介于关系数据库和非关系数据库(NoSQL)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. mongoDB介绍 mon ...