真正把kmp算法中的next数组含义和求法讲明白Aninock

next数组我是这样定义的:该位置前面字符串的最长相同的真前缀和真后缀长度。

直接看这个字符串,ABABDABABAE:

中间一行是字符串的位置下标

首先,来看next数组第一个应该填什么。

很明显,A这个位置前面压根没字符了,所以也不存在最长相同真前后缀。

按照定义,把next数组第一个填0(实际一般填-1,这个是为什么后面再解释)。

那么看第二个,字符是B,那么它前面是字符串A。

这里注意一下,求最长相同真前后缀,真前缀是不包括自身的,真后缀同理。

那么也很显然,A也没有真前后缀,更别说相同的真前后缀了。

所以next数组第二个也填0。

看第三个,字符是A,那么它前面是字符串AB。

这次有真前后缀了,真前缀只有一个A,真后缀只有一个B。

相同的真前后缀长度还是0。

看第四个,字符是B,那么它前面是字符串ABA。

ABA的真前缀有A,AB。真后缀有A,BA。

好,这次不是0了,A和A相同。

因此最长的相同的真前后缀长度是1。

所以next数组第4个填1。

后面不用多说。按照这思路求出来的next数组应该是这个样子的:

这里我说个重要点:

next数组存的不是这个位置的最长的相同的真前后缀长度,它存的是这个位置前面的字符串的最长的相同的真前后缀长度。

所以看图中,最后E的位置,这时候字符串是ABABDABABAE其实根本没相同的真前后缀!

这个3指的是E前面的ABABDABABA最长的相同的真前后缀长度(即ABA)。

好,现在知道啥是next数组。但是这玩意怎么求呢?

我们是人,一眼看出相同前后缀。电脑不能看出来。

显然要设计一种算法,来求一个字符串的next数组。

有人说暴力跑一遍不就知道了?

别忘了,我们发明KMP算法就是简化字符串匹配的,你这里暴力匹配也谈不上简化二字了。

大家看数据结构书,看网上都会发现其实有一种简便方法让计算机快速求next数组。

这里先不贴代码。

先看一种情况:

对于上面举的例子,怎么求next[8]呢?

把原数组称为array。

仔细想想就会发现,这个next数组其实是一个个按顺序求值的。

虽然不知道next[8](也就是字符B)对应的next数组值是多少,但是前面是已知的。

能不能根据前面已知的next数组值来推导?

注意到next[7]=2,这并不是指array[7]对应位置的字符串最长的相同的真前后缀长度。

前面已经说过这个2指的是array[7]对应位置前面字符的相同真前后缀,并不包括array[7]该位置本身。

实际上arrary[7]是A对next[7]有影响吗?根本没有。把arrary[7]换成K这个位置next[7]也是2,这是由前面决定的。

显然,这个字符A决定是后面next[8]的值,因为next[8]求得是array[0]到array[7]这个字符串。

这也就是说:要知道next[8]的值只需要看next[7]和arrary[7]即可!

OK,我们再来看这个2,它是指该位置前面的字符串最长的相同的真前后缀长度为2。

也就是ABABDAB这个字符串,它们前面两个字符是AB,最后两个字符也是AB。

接下来我们知道,数组都是由0开始计数的。

那么其实array[next[7]]=array[2]=原数组的第三个。

回到例子,

我们知道next[7]=2,也就是array[7]前面两个(array[5]和array[6])和字符串开头(array[0]和array[1])两个相同。

显然,如果array[7]=array[2]=A,

那么array[8]前面三个(array[5]array[6]array[7])和字符串开头(array[0]和array[1]array[2])三个相同。

如果array[next[m]]==array[m],那么next[m+1]=next[m]+1;

比如说next[m]=K,意味着m位置前面字符串前K个和后K个相同(这里的后K个,也就是m位置前K个)。

又由于数组从0计数,所以说array[next[m]]==array[K],是指数组的第K+1个元素。也就是第一个不是前缀的位置!

现在m位置前字符串的前K个和后K个相同。而array[]数组的第K+1个元素又等于array[m]。

那么m+1个位置前字符串的前k+1个和后k+1个相同。

接下来讨论array[next[m]]!=array[m]的情况。

还是这个例子,

next[10]应该是多少?

(array[9]=4,因为array[9]前面字符串是ABABDABAB相同部分是ABAB长度为4)

如图,

array[next[9]]=array[4]=D

而array[9]=A

array[next[9]]!=array[9],

那么next[10]也不等于next[9]+1了。

我们之所以能只比较两个位置的值等不等就能确定最长前后缀,是因为前面已经求出来相同的地方了。

我们只要看array[4]和array[9]不同,是因为前面4个肯定相同,因为next[9]=4;

OK,取长度为5的前后缀不同,那么短一点的前后缀有可能会相同。

我们看看取4个的情况:

假如4长度的前后缀相同的话,就意味着array[0~3]=array[6~9]

也就意味着array[0~2]=array[6~8]

如图,只有绿圈里相同,我们才有必要比较array[3]是不是等于array[9]。

问题是怎么知道绿圈里相不相同。

我们仔细想一下,蓝圈是已知next[9]=4而相同的前后缀。

所以前后两个蓝色圈内字符串是完全相同的。

如果绿圈也相同,那不是代表绿圈是蓝色圈中字符串的相同前后缀?

而我们能不能知道蓝圈内的相同前后缀是什么?

当然可以:

next[4]位置存储的就是前面4个的最长相同前后缀。

我们看next[9]=4。就是粉色圈子里的部分,两个字符串相同。

而next[4]=2。就是蓝色圈子里的部分,这四个部分都相同。

那么现在看橙色部分,就只要比较array[9]=array[2],因为arr[0~1]和arr[7~8]肯定相同了,

比较发现确实array[9]=array[2],那么得出结论:arrar[10]=3;

分析一下,next[9]=4,就是前9个字符中前4个和后4个相同。

那么,next[next[9]]=next[4]。

也就是第一个不属于前缀的位置,而next[4]代表是该位置前面字符串,就是之前的前缀。

next[4]=2,也就是之前的前缀的相同前后缀的长度。

这也就是为什么上面第一种假设肯定不行了,因为next[next[9]]=next[4]=2。

取三个前缀后缀肯定不等,等的话next[4]就等于3了。

因此那一种情况中array[9]和array[3]都没有继续比较的必要了。

如果一直不等呢?

将arrat[9]改为E:

明显array[2]不等于array[9];

那么就按照之前思路继续取:next[next[next[9]]]=next[next[4]]=next[2]=0。

比较array[9]和array[0],还是不等。

但是next[0]=0,继续嵌套不还是next[0]吗?

所以将next[0]=-1;

next[next[next[9]]]=next[next[4]]=next[0]=-1;

OK,检测到-1就没必要继续嵌套了。

该位置不存在相同前后缀了。

再举个例子

如图,将之前array[3]和arrar[8]改成E:

array[9]等于array[next[9]]吗?(array[next[9]]=array[4])

(等于的话next[10]=next[9]+1=5)

不等于,比较array[9]和array[next[next[9]]](array[next[next[9]]]=array[next[4]]=array[0])

array[9]=array[0]=A那么,next[10]=next[4]+1=1

(不等于的话next[next[next[9]]]=next[next[4]]=next[0]=-1;next[10]=0)

设置arrry[0]=-1;

如果array[next[m]]!=array[m],

令t=m;t=next[t]

比较array[next[t]]和array[m],相同的话next[m]=next[t]+1;

不同的话t=next[t]继续比较。

当t=-1时,next[m]=0;

下面是随意找的一串代码:

1voidGetnext(intnext[],Stringt)2{3intj=0,k=-1;4next[0]=-1;5while(j

THE END
1.什么是算法?算法设计有哪些基本方法?算法基本设计方法算法设计中列举法的效率问题如何解决? 在算法设计中,列举法(也称为穷举法或枚举法)是一种通过逐一列举所有可能情况来解决问题的方法。然而,列举法的效率问题主要在于其计算复杂性通常随着问题规模的增加而指数级增长,这使得它在处理大规模问题时效率低下。 https://blog.csdn.net/m0_61505785/article/details/144050327
2.什么是算法?常见的算法分类有哪些?什么是算法?常见的算法分类有哪些?相关知识点: 试题来源: 解析 答:算法指解决问题的方法或步骤,是计算机科学的核心内容之一。其包括:输入、输出、有限性、明确性和有效性五个要素,通常使用程序语言来描述。常见的算法分类包括: 贪心算法:采取当前最优的选择,从而使最终结果尽可能接近最优解。 动态规划算法:将问题https://easylearn.baidu.com/edu-page/tiangong/questiondetail?id=1767773586707891229&fr=search
3.K.O.《算法导论》——寻找算法真正入门路径这本要被淹没了,因为它有点阳春白雪,理论高度比前几本要高出不少。可贵的是作者研究的理论,是真正的 算法专业的理论,而不是《算法导论》那样用那么多数学说事。 作者质疑「计算机科学」这个名字,提出CS是研究计算,而不是计算机,这个观点让我印象很深刻。 https://www.douban.com/note/795313909
4.真正统治世界的十大算法10. 随机数生成 现在我们还没有一个“真正的”随机数生成器,但我们已经有了一些伪随机数生成器,这够用了。随机数生成器的用途非常广泛,从互联联络、数据加密、安全哈希算法、电子游戏、人工智能、优化分析,到问题的初始条件、金融等等,都有它们 最后,我想强调一下,上面这个列表经供参考,它并不完整。因为在机器学习https://maimai.cn/article/detail?fid=395232582&efid=aRtcr75j-oVVPJXATXh9WQ
5.冯少辉:真正支配世界的十种算法直白地讲,算法是指一切经过明确定义的计算过程,其将某个或者某组值作为输入内容,并产生某个或者某组值作为输出结果。因此,算法代表的是一系列计算步骤,用于将输入转换为输出。——资源来源:Thomas H. Cormen 与 Chales E. Leiserson(2009年),《算法导论》第3版。 http://yunrun.com.cn/tech/5470.html
6.这一次,真正理解回溯算法其他这一次,真正理解回溯算法 理解“回溯算法” 若人生可重来,如何才能在岔路口做出最正确选择,让自己的人生“最优”? 贪心算法,在每次面对岔路口的时候,都做出看起来最优的选择,期望这一组选择可以使得我们的人生达到“最优”。但不一定能得到的是最优解。https://www.saoniuhuo.com/article/detail-33254.html
7.关于“信息茧房”,误解真相和破解可见,真正的算法推荐系统远比“喜欢看蛋糕推荐蛋糕”要复杂得多,也深入得多、智能得多。把锅甩给技术和算法从来都是最简单不费力的方法,只不过这样一来人们就会拒绝更深入的反思和改变。 美国明尼苏达大学计算机系专门进行了实验,让两组人同时在协同过滤算法推荐的平台上获取内容:一组人对推荐结果进行“跟随”,一组https://zhuanzhi.ai/document/ea4415761381e6950b21c3d07728dec4?from=doc_sim_rec
8.为什么要稳定币?算法稳定币有什么用途?币种百科区块链2、算法稳定币旨在提高价格行情稳定性,无需中央机构,而且是去中心化的。这一般根据对供应进行预编程以配对财产情况来完成。 一个“算法”稳定币要想真正成功,这需要四个基本功能: 1、加速——迅速拓展能力,而且仍然能够抵挡主要的市场震荡; 2、偿付能力——对稳定币的支持的认可和信心; https://www.jb51.net/blockchain/889920.html
9.Netflix的海量封面图是怎么设计出来的?960万张图只选一张AVA 系统:真正的算法筛图 尽可能多、尽可能丰富、尽可能符合规律的的封面图,能给 Netflix 带来最直接的转化,精心挑选封面图这个事情……工作量太大了。AVA 系统就是用来解决这个「大量的封面图从哪里来」的问题。 著名剧集《怪奇物语》一集有大约 86000 个静态帧,这意味着10集一季的剧集当中,可以筛出接近 900https://www.uisdc.com/netflix-ava
10.“网络平台算法治理”系列评算法本身中立,但算法的规则制定、模型设计、数据分析等并非完全客观;算法固然是商业秘密,但算法应用涉及的往往是社会公共利益,滥用算法危害的是千千万万消费者的合法权益。 要真正打破算法“黑箱”,需要健全算法定价机制和信息披露机制,提升平台算法逻辑、定价规则等的透明度。此外,要畅通消费者的举报途径,http://bj.news.cn/20241127/0edbbb3abc2e4e40a18981a029ee4e77/c.html
11.透视算法黑箱:数字平台的算法规制与信息推送异质性本研究借鉴实验和逆向工程方法,通过设置若干虚拟账号与数字平台进行长时间真实互动,以尝试真正进入算法的政治化空间,分析算法规制对用户信息获取异质性的影响。实证结果揭示了数字时代算法规制的高度复杂化、精细化和隐蔽化。从信息主题维度看,算法增加了个体获得https://mp.weixin.qq.com/s?__biz=MjM5OTgyMzIxNw==&mid=2649727718&idx=1&sn=3b38a41b115648efa60d9e3f39ea6cc7&chksm=bf2e90f8885919ee268f3ed985786467775399b55aa528bae23ffe57677fac2fa3828831d717&scene=27
12.2023考研英语同源外刊文章:算法可能永远不会真正弄明白人类6、entrench [?n?trent?] vt. 确立,牢固;用壕沟围住;挖掘 vi. 侵犯;挖掘壕沟 7、evict [v?kt] vt. 驱逐;逐出 综上是-2023考研英语同源外刊文章:算法可能永远不会真正弄明白人类,希望对备考2023考研的小伙们有所帮助!预祝考生2023考研凯旋归来!https://www.kyjxy.com/beikao1/yingyu/1143.html
13.图形图像算法中必须要了解的设计模式(1)腾讯云开发者社区真正的识别处理,进行ORI区域识别。 这些预处理算法的顺序不同,将对结果产生很大的影响。 下面我们将以图像的边缘提取算法为例演示整个处理过程,为简单起见,假设有两个预处理过程(灰度化、梯度化)和一个核心算法(二值化边缘提取)。有两种处理顺序,分别如下: https://cloud.tencent.com/developer/article/1165835
14.以质取胜范文12篇(全文)总体看, 这两则案例中教师都在尝试运用新理念指导课堂教学, 都能给学生独立思考的时间, 在教学过程中强调通过“算法多样化”来培养学生的发散性思维。但教师都未能真正理解“算法多样化”的内涵, 两节课均未真正落实“算法多样化”。 案例1是笔者上公开课时的一个片段。笔者尊重学生的想法, 让他们选择自己喜欢的算法https://www.99xueshu.com/w/ikeyan9azu96.html