KMP深入浅出

这里看格式更佳:个人blog      &  知乎上的提问

既然这样问,就默认你已经大致明白KMP的原理吧。

举个通俗的例子解释KMP算法中NEXT[J]:

字符串:abcX

子串     : abcd

当比较到d与X的时候,最原始的算法是子串向后移动一位继续比较

字符串:abcX

子串     :   abcd

而KMP则利用已知信息abc前3个字符是相等的,j从0跳到3,向后移动3位,比较a与X

字符串:abcX

子串     :       abcd

=======================================================

当例子变复杂一点的时候:

字符串:abcabX

子串     : abcabz

根据kmp原理可知,子串应该向后移动到

字符串:abcabX

子串     :       abcabz

这样的位置而不是

字符串:abcabX

子串     :           abcabz

原因就是子串里面有重复的值(即"前缀"和"后缀"有相似)。

=======================================================

当子串是正常的时候,我们向后移动的位数应该就是子串比较了多少位直到不相等(就是j值)(懂kmp的你懂的。。),如:

abcabd |       abcabg  |      abcdefg  |

abc       |      ab           |            de     |

后移3位 |   后移两位  |      后移2位   |

但是,就是因为子串不是单纯的每个不相等(前后缀不相似),所以就需要我们的next[j]了!!

比如:abcabgabcabx

abcabx

这里原本是可以直接向后移动j=5,5位的,

abcabgabcabx

abcabx

但是因为abcabx中有相似,所以只能向后移动5-2=3位了

abcabgabcabx

abcabx

而要减去的这个2,则是next[5]的所存储的东西!

所以next[j]的作用就是,保存当有相似子串时,要减去的数(相似度)

那么,对于不相似的情况,也可以范化为,相似度为0,next[j]=0,

所有子串比较到不相等的情况时,都后移j-next[j]位

这就是next[j]的作用。

下面有傻逼死:

"前缀"和"后缀"。

"前缀"指除了最后一个字符以外,一个字符串的全部头部组合;"后缀"指除了第一个字符以外,一个字符串的全部尾部组合。

2."前缀"和"后缀"相似度,即next数组的值,即《部分匹配表》(Partial Match Table)是什么。

那么,如何来计算呢?

先明确"前缀"和"后缀"相似度是什么。

如在abcabx中,

当j=0时只有a,前缀和后缀都为空集,共有元素的长度为,next[j]=0;

当j=1时,ab的前缀是a,后缀是b,如上,next[j]=0;

当j=2时,abc的前缀是a,ab,后缀是bc,b,如上,next[j]=0;

当j=3时,abca的前缀是a,ab,abc,后缀是bca,ca,a, 前缀跟后缀有一个交集(相似)a,长度为1,所以next[j]=1;

当j=4时,abcab的前缀是a,ab,abc,abca,后缀是bcab,cab,ab,b, 前缀跟后缀有一个最大交集(相似)ab,长度为2,所以next[j]=2;

当j=6时,abcabx的前缀是a,ab,abc,abca,abcab,后缀是bcabx,cabx,abx,bx,共有元素的长度为,next[j]=0;

时间: 2024-10-28 09:43:48

KMP深入浅出的相关文章

下载-深入浅出Netty源码剖析、Netty实战高性能分布式RPC、NIO+Netty5各种RPC架构实战演练三部曲视频教程

下载-深入浅出Netty源码剖析.Netty实战高性能分布式RPC.NIO+Netty5各种RPC架构实战演练三部曲视频教程 第一部分:入浅出Netty源码剖析 第二部分:Netty实战高性能分布式RPC 第三部分:NIO+Netty5各种RPC架构实战演练

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

hiho 1015 KMP算法 && CF 625 B. War of the Corporations

#1015 : KMP算法 时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和小Ho是一对好朋友,出生在信息化社会的他们对编程产生了莫大的兴趣,他们约定好互相帮助,在编程的学习道路上一同前进. 这一天,他们遇到了一只河蟹,于是河蟹就向小Hi和小Ho提出了那个经典的问题:“小Hi和小Ho,你们能不能够判断一段文字(原串)里面是不是存在那么一些……特殊……的文字(模式串)?” 小Hi和小Ho仔细思考了一下,觉得只能想到很简单的做法,但是又觉得既然河蟹先生这么说了,就

hdu2328 Corporate Identity 扩展KMP

Beside other services, ACM helps companies to clearly state their "corporate identity", which includes company logo but also other signs, like trademarks. One of such companies is Internet Building Masters (IBM), which has recently asked ACM for

看完深入浅出的Javascript,简单写下

628页,几天的时间,慢慢的从头看过来,也一遍遍实践过来,一些概念一直都知道,但是程序的世界就是这样,所有的东西就是那些,但是就是喜欢看这种深入浅出的书,就是喜欢看自己知道的东西,能讲出来多少不一样的角度,真的还是有很多收获. 这也许就是技术的魅力,可以给你一个安心的地方 但是这里有的是无止境的学习,而且这里也会交给你做事的道理,也许不太能教会你职场的学问,不能教你怎么做生意,但是这里教给你的,内化在心里的是别人谁也没有办法抢走的,这就是我们学习语言的乐趣所在. 即使是半路出家,及时我接触网络的

Rxjava+ReTrofit+okHttp深入浅出-终极封装

Rxjava+ReTrofit+okHttp深入浅出-终极封装 背景: 学习Rxjava和retrofit已经很长时间了,功能确实很强大,但是使用起来还是有点复杂,代码的重复性太高,所以决定把基于retrofit和rxjava的处理统一封装起来,实现的功能: 1.Retrofit+Rxjava+okhttp基本使用方法 2.统一处理请求数据格式 3.统一的ProgressDialog和回调Subscriber处理 4.取消http请求 5.预处理http请求 5.返回数据的统一判断 效果: 封装

KMP算法详解

这几天学习kmp算法,解决字符串的匹配问题,开始的时候都是用到BF算法,(BF(Brute Force)算法是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果.BF算法是一种蛮力算法.)虽然也能解决一些问题,但是这是常规思路,在内存大,数据量小,时间长的情况下,还能解决一些问题,但是如果遇到一些限制时间和内存的字符串问

2016——3——16 kmp习题

1.传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2725 题目大意:找一个串在另一个串中出现的次数 题解:kmp(纯裸题) 2.传送门:http://begin.lydsy.com/JudgeOnline/problem.php?id=2732 题目大意:给你一个字符串,让你求出最大重复周期(最大周期不和本身重合) 题解:kmp或者扩展kmp(但我并未用这种方法),我用的是kmp,但是一直WA,原来是求next数组把while写成了

KMP算法

1 /* next数组是KMP算法的关键,next数组的作用是:当模式串T和主串S失配 2 * ,next数组对应的元素指导应该用T串中的哪一个元素进行下一轮的匹配 3 * next数组和T串相关,和S串无关.KMP的关键是next数组的求法. 4 * 5 * ——————————————————————————————————————————————————————————————————— 6 * | T | 9 | a | b | a | b | a | a | a | b | a | 7