来去学习之---KMP算法--next计算过程
一、概述
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计算过程的更多相关文章
- 学习笔记-KMP算法
按照学习计划和TimeMachine学长的推荐,学习了一下KMP算法. 昨晚晚自习下课前粗略的看了看,发现根本理解不了高端的next数组啊有木有,不过好在在今天系统的学习了之后感觉是有很大提升的了,起 ...
- [一本通学习笔记] KMP算法
KMP算法 对于串s[1..n],我们定义fail[i]表示以串s[1..i]的最长公共真前后缀. 我们首先考虑对于模式串p,如何计算出它的fail数组.定义fail[0]=-1. 根据“真前后缀”的 ...
- KMP算法之查找模式串在源串中出现的次数
问题描述: 给定两个字符串T, P.查找字符串P在字符串T中出现的次数. 解决方法: 典型的KMP算法的题目,在此使用的KMP算法为算法导论上介绍的算法.下一篇文章将详细介绍KMP算法的计算过程. 题 ...
- 关于《数据结构》课本KMP算法的理解
数据结构课上讲的KMP算法和我在ACM中学习的KMP算法是有区别的,这里我对课本上的KMP算法给出我的一些想法. 原理和之前的KMP是一样的https://www.cnblogs.com/wkfvaw ...
- KMP算法 Next数组详解
题面 题目描述 如题,给出两个字符串s1和s2,其中s2为s1的子串,求出s2在s1中所有出现的位置. 为了减少骗分的情况,接下来还要输出子串的前缀数组next.如果你不知道这是什么意思也不要问,去百 ...
- 字符串匹配的 KMP算法
一般字符串匹配过程 KMP算法是字符串匹配算法的一种改进版,一般的字符串匹配算法是:从主串(目标字符串)和模式串(待匹配字符串)的第一个字符开始比较,如果相等则继续匹配下一个字符, 如果不相等则从主串 ...
- 数据结构4_java---顺序串,字符串匹配算法(BF算法,KMP算法)
1.顺序串 实现的操作有: 构造串 判断空串 返回串的长度 返回位序号为i的字符 将串的长度扩充为newCapacity 返回从begin到end-1的子串 在第i个字符之前插入字串str 删除子串 ...
- 程序员的算法课(11)-KMP算法
版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/de ...
- KMP算法,看这篇就够了!
普通的模式匹配算法(BF算法) 子串的定位操作通常称为模式匹配算法 假设有一个需求,需要我们从串"a b a b c a b c a c b a b"中,寻找内容为"a ...
随机推荐
- pyton 封装
定义:在类中将方法和属性隐藏起来 一.私有化 1.格式 __名字,在名字前加双下划线 2.私有化对象 对象属性 静态属性 普通方法 3.作用 1)在类的外面不能直接调用类的方法和属性 2)类的属性值不 ...
- LeetCode动画 | 1038. 从二叉搜索树到更大和树
今天分享一个LeetCode题,题号是1038,标题是:从二分搜索树到更大和数. 题目描述 给出二叉搜索树的根节点,该二叉树的节点值各不相同,修改二叉树,使每个节点 node 的新值等于原树中大于或等 ...
- Wordpress4.9.6 任意文件删除漏洞复现分析
第一章 漏洞简介及危害分析 1.1漏洞介绍 WordPress可以说是当今最受欢迎的(我想说没有之一)基于PHP的开源CMS,其目前的全球用户高达数百万,并拥有超过4600万次的超高下载量.它是一个开 ...
- MySQL-5.7.29 的安装与配置
解压缩,我这里的解压路径是:D:\Program Files\Java MySQL-5.7.29下载地址:https://www.jianguoyun.com/p/DcKSfd8Q6LnsBxiY8c ...
- 【自制操作系统06】终于开始用 C 语言了,第一行内核代码!
一.整理下到目前为止的流程图 写到这,终于才把一些苦力活都干完了,也终于到了我们的内核代码部分,也终于开始第一次用 c 语言写代码了!为了这个阶段性的胜利,以及更好地进入内核部分,下图贴一张到目前为止 ...
- git hub安装
windows下GitHub的安装.配置以及项目的上传过程详细介绍 阅读目录 概要 操作必备 GitHub的安装 Git的初始配置 本地Git与远程GitHub连接的建立 将本地项目上传到GitHub ...
- Leetcode 题目整理-6 Swap Nodes in Pairs & Remove Duplicates from Sorted Array
24. Swap Nodes in Pairs Given a linked list, swap every two adjacent nodes and return its head. For ...
- 理解和运用Java中的Lambda
前提 回想一下,JDK8是2014年发布正式版的,到现在为(2020-02-08)止已经过去了5年多.JDK8引入的两个比较强大的新特性是Lambda表达式(下文的Lambda特指JDK提供的Lamb ...
- centos6.8安装lnmp
一.配置CentOS 第三方yum源(CentOS默认的标准源里没有nginx软件包) [root@localhost ~]# yum install wget #安装下载工具wget[root@lo ...
- mysql笔记(暂时)
2018-05-28 create table cms_user(id int key auto_increment,username varchar(20),password varchar(20) ...