来去学习之---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 ...
随机推荐
- 【Java并发基础】使用“等待—通知”机制优化死锁中占用且等待解决方案
前言 在前篇介绍死锁的文章中,我们破坏等待占用且等待条件时,用了一个死循环来获取两个账本对象. // 一次性申请转出账户和转入账户,直到成功 while(!actr.apply(this, targe ...
- 记第一场cf比赛(Codeforces915)
比赛感想 本来21:05开始的比赛,结果记成21:30了...晚了25分钟才开始[捂脸] 这次是Educational Round,所以还比较简单. 前两道题一眼看去模拟+贪心,怕错仔细看了好几遍题, ...
- [bzoj2038] [洛谷P1494] [2009国家集训队] 小Z的袜子(hose)
Description 作为一个生活散漫的人,小Z每天早上都要耗费很久从一堆五颜六色的袜子中找出一双来穿.终于有一天,小Z再也无法忍受这恼人的找袜子过程,于是他决定听天由命-- 具体来说,小Z把这N只 ...
- java小心机(3)| 浅析finalize()
每天进步一丢丢,连接梦与想 如果你停止就是谷底,如果你还在努力就是上坡 系列文章 java"小心机"(1)[资源彩蛋!] java小心机(2)| 重载和构造器的小细节 预备知识 J ...
- 把本地仓库同步到github上去
1.愚蠢的没有进入之前设定的工作目录就开始用 git remote add origin https://github.com/bobowa/learngit.git 这个命令上传,报错如下 fata ...
- pywin32 获取 windows 的窗体内文本框的内容
用 spy++去确认找到了文本框的句柄了. 用函数 win32gui.SendMessage 获取不了文本框的文本内容,用 str 类型的参数接收获取的内容的话没有获取到东西,而用 PyBuffer ...
- CSS-09-背景属性
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- PYTHON经典算法-完美平方
问题描述: 给定一个正整数n,找到若干个完全平方数(例如:1,4,9),使得 它们的和等于n,完全平方数的个数最少. 问题示例: 给出n=12,返回3,因为12=4+4+4:给出n=13,返回2,因为 ...
- STM8 ADC 多个通道连续扫描缓冲区数据带中断模式的正确写法
近日调试了STM8S的ADC采集多通道数据的程序,按照之前的立即,将ADC1设置为:扫描模式,连续采集,数据缓存模式,中断使能后应该可以在中断后读取到数值了,可是无论怎样都只能读取到第一个缓冲器的数据 ...
- Leetcode | 刷题日记(1)
本文记录个人刷题记录 推荐两个刷题网站: 地址:https://leetcode.com/ 另外一个地址:http://www.lintcode.com/ 1.Write a SQL query to ...