一、概述

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. Spring Boot 入门(十二):报表导出,对比poi、jxl和esayExcel的效率

    本片博客是紧接着Spring Boot 入门(十一):集成 WebSocket, 实时显示系统日志写的 关于poi.jxl和esayExcel的介绍自行百度. jxl最多支持03版excel,所以单个 ...

  2. matplotlib 条形图

    一.特点 离散数据,数据之间没有直接的关系 二.分类 1.垂直条形图 bar(x, height, width=0.8) # x 为x轴 # height 为y轴 # width 为 条形图的宽度 例 ...

  3. 网站 cache control 最佳实践

    推荐阅读: 2020年软件开发趋势 高并发案例 - 库存超发问题 负载均衡的分类及算法 异地多活架构 Postman 的替代品来了 有时,当第二次访问网站时,看起来比较怪,样式不正常. 通常,是因为 ...

  4. mva 的 第一弹 ASP.NET SignalR

    弹弹弹 弹走 占位 补齐

  5. PHP 1-16课

    浏览器      使用火狐浏览器 认识标签 个人使用的编辑器:HbuilderX 标签是HTML5的基本结构,标签分为双标签和单标签 例如:<li> </li> <br ...

  6. view 视图函数

    一 Django的视图函数view 一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应. 响应可以是一张网页的HTML内容,一个重定向,一个404错 ...

  7. postman发送请求的简单操作

    发送请求常用的是post和get 两者的区别是: 1.post比get安全,因为参数直接暴露在url中,不能用来传递敏感信息 2.get参数通过url传递,post放在request body中 3. ...

  8. .net core3.1 web api中使用newtonsoft替换掉默认的json序列化组件

    在微软的文档中,有着较为详细的替换教程 https://docs.microsoft.com/zh-cn/aspnet/core/web-api/advanced/formatting?view=as ...

  9. 目标检测——深度学习下的小目标检测(检测难的原因和Tricks)

    小目标难检测原因 主要原因 (1)小目标在原图中尺寸比较小,通用目标检测模型中,一般的基础骨干神经网络(VGG系列和Resnet系列)都有几次下采样处理,导致小目标在特征图的尺寸基本上只有个位数的像素 ...

  10. ATL的GUI程序设计(1)

    from:http://blog.titilima.com/atlgui-1.html 第一章 不能免俗的"Hello, World!" 在这一章里,就像所有的入门级教程一样,我也 ...