KMP算法详解
- 格式:doc
- 大小:191.00 KB
- 文档页数:14
KMP算法Next数组详解题⾯题⽬描述如题,给出两个字符串s1和s2,其中s2为s1的⼦串,求出s2在s1中所有出现的位置。
为了减少骗分的情况,接下来还要输出⼦串的前缀数组next。
如果你不知道这是什么意思也不要问,去百度搜[kmp算法]学习⼀下就知道了。
输⼊输出格式输⼊格式:第⼀⾏为⼀个字符串,即为s1(仅包含⼤写字母)第⼆⾏为⼀个字符串,即为s2(仅包含⼤写字母)输出格式:若⼲⾏,每⾏包含⼀个整数,表⽰s2在s1中出现的位置接下来1⾏,包括length(s2)个整数,表⽰前缀数组next[i]的值。
输⼊样例:ABABABCABA输出样例:130 0 1说明时空限制:1000ms,128M数据规模:设s1长度为N,s2长度为M对于30%的数据:N<=15,M<=5对于70%的数据:N<=10000,M<=100对于100%的数据:N<=1000000,M<=1000题解这是⼀道KMP裸题(模板题。
)我就是拿着它学习⼀下KMP算法其实原来我学过KMP算法但是⼀直没有弄懂next(跳转)数组是如何求出来的。
最近花了⼀个下午⾃⼰研究了⼀下KMP算法现在终于觉得KMP很简单了~现在直接说next数组把⾄于有什么作⽤,next数组是⼲什么的,请⾃⾏百度,有很多dalao总结的⾮常到位,看⼀看就会明⽩。
好,来说next数组并不⽤在意这⼀坨⿊的是什么东西,我们就假设他是我们要求next数组的字符串。
next数组求的东西就是从起始位置到当前位置最长的相等的前缀和后缀的长度。
(举个例⼦China的前缀有:C、Ch、Chi、Chin、China ;后缀有a、na、ina、hina、China)我们继续,如上图红⾊的是当前位置(设为j)前,所匹配上的最长前缀和后缀,蓝⾊的是当前要匹配的位置。
那么,我们就拿当前位置和原来匹配到的最长前缀的后⼀位相⽐较如果两个位置相同,显然,可以和前⾯的红⾊连在⼀起,此时就有next[j]=next[j-1]+1如果两个位置不相同,根据next数组的性质,显然的,你的当前的相等的前缀和后缀只能够继续向前找,也就是说,你当前的next数组⼀定会减⼩。
kmp 序列碱基KMP算法是一种字符串匹配算法,主要应用于字符串匹配和搜索领域,在生物信息学中,KMP序列匹配算法也是一个常用的处理甲基化数据的方法之一。
KMP算法是一种高效的字符串匹配算法,它的核心思想是通过计算匹配串的前缀表格来快速匹配目标串。
同样的,KMP序列匹配算法也是通用的字符串匹配算法。
在生物信息学中,KMP序列匹配算法可以用来处理基因组中的碱基序列,如DNA,RNA等。
KMP序列匹配算法的基本流程是:1.通过计算目标串的匹配表格来快速匹配目标串中的子串。
该表格的计算方式是使用特定的规则来填充每一行,其中每一行代表了目标串中的一个前缀。
2.当我们要查找匹配模式串在目标串中出现的位置时,我们可以通过比对模式串和目标串的每个字符来快速移动模式串,并检查当前字符是否匹配。
如果匹配,我们就继续检查模式串的下一个字符。
3.匹配模式字符串的过程中,如果我们遇到了不匹配的字符,我们可以利用匹配表格来快速移动模式串。
这样,我们就可以避免重复比对不必要的字符,快速地找到目标串中所有匹配模式串的位置。
在生物信息学中,碱基序列是一个重要的概念。
碱基是生物体中最小的化学单元,它们组成了DNA和RNA分子中的基本单元。
每个碱基都包含一个氮原子基团和一个碳基团,它们通过一系列的化学键连接在一起。
序列是由碱基组成的有序排列,它是生物信息学中基本的概念之一。
其中,DNA和RNA序列是生物学研究中最常见的序列类型,这是因为它们在生物体中担任着许多关键的功能,如遗传信息的传递、蛋白质合成等。
KMP序列匹配算法可以用来处理基因组中的碱基序列,其主要步骤是将模式串和目标串中的碱基序列转换为字符串,然后使用KMP算法来快速查找匹配结果。
在生物信息学中,KMP序列匹配算法的应用非常广泛。
例如,我们可以使用KMP算法来查找基因组中的DNA序列中某个特定的碱基片段,或者对不同物种中的DNA序列进行比较等。
总之,KMP序列匹配算法是一种强大的字符串匹配算法,在生物信息学中也是一个重要的工具,在处理DNA、RNA等碱基序列方面有着广泛的应用。
KMP算法(改进的模式匹配算法)——next函数KMP算法简介KMP算法是在基础的模式匹配算法的基础上进⾏改进得到的算法,改进之处在于:每当匹配过程中出现相⽐较的字符不相等时,不需要回退主串的字符位置指针,⽽是利⽤已经得到的部分匹配结果将模式串向右“滑动”尽可能远的距离,再继续进⾏⽐较。
在KMP算法中,依据模式串的next函数值实现字串的滑动,本随笔介绍next函数值如何求解。
next[ j ]求解将 j-1 对应的串与next[ j-1 ]对应的串进⾏⽐较,若相等,则next[ j ]=next[ j-1 ]+1;若不相等,则将 j-1 对应的串与next[ next[ j-1 ]]对应的串进⾏⽐较,⼀直重复直到相等,若都不相等则为其他情况题1在字符串的KMP模式匹配算法中,需先求解模式串的函数值,期定义如下式所⽰,j表⽰模式串中字符的序号(从1开始)。
若模式串p 为“abaac”,则其next函数值为()。
解:j=1,由式⼦得出next[1]=0;j=2,由式⼦可知1<k<2,不存在k,所以为其他情况即next[2]=1;j=3,j-1=2 对应的串为b,next[2]=1,对应的串为a,b≠a,那么将与next[next[2]]=0对应的串进⾏⽐较,0没有对应的串,所以为其他情况,也即next[3]=1;j=4,j-1=3 对应的串为a,next[3]=1,对应的串为a,a=a,所以next[4]=next[3]+1=2;j=5,j-1=4 对应的串为a,next[4]=2,对应的串为b,a≠b,那么将与next[next[4]]=1对应的串进⾏⽐较,1对应的串为a,a=a,所以next[5]=next[2]+1=2;综上,next函数值为 01122。
题2在字符串的KMP模式匹配算法中,需先求解模式串的函数值,期定义如下式所⽰,j表⽰模式串中字符的序号(从1开始)。
若模式串p为“tttfttt”,则其next函数值为()。
KMP算法(超容易理解的next数组求法)我想,既然知道KMP算法了,⾃然对于其具体如何运作也是有⼀定的了解的,我也没必要再⼤费⼝⾆讲废话,⼤家⼀定查过很多资料,但是其实也都看的⼀知半解,好像⾃⼰懂了但是⼜没有理解透,特别是next数组的求法感觉很蛋疼,那么我就来给⼤家解决⼀下这个next数组的问题吧,如果对KMP算法没有概念的同学请先去查清楚再过来看看。
先讲⼀下我们后续讲解的⼀些规范,我们next数组、以及模式串都是从数组的下标1开始储存的,注意不是0!(这样操作⽅便⼀点)下⾯列出⼀个next数组:模式串A B A B A B Bj1234567next[j]0112345很多⼈可能对这个next数组的理解就是不正确的,我们来好好解释⼀下:第⼀个元素的next值,即next[1],默认是0,这是规定的,0则表⽰从头开始⽐较那么很多⼈会疑惑,那上⾯这个例⼦中,j=2的时候如果不匹配,不也是应该从头开始⽐较吗?那么为什么next[2]不是0⽽是1呢?好,你可能会机智地说,next[1]=0是你规定死的,⽽你的模式串⼜是从下标为1的地⽅保存起来的,当然next[2] = 1啦!我们知道KMP算法的匹配是通过next数组慢慢往前回复(如果匹配失败的话)的⼀个过程,那么经过next数组返回后,我们究竟是从哪⾥开始⽐较呢?是从返回的那⼀个开始,还是它的前⼀个,亦或是后⼀个?这就涉及对next数组的真正的理解了,我们来好好理⼀理,这个next数组到底是怎么⼀回事!所谓next数组的返回,其实是前⾯有⼀部分是重叠的,才能这样回退。
⽤⽂字可能很难描述,我们直接拿上⾯的来举例。
j = 4的时候,这个B前⾯的A和第⼀个A是相同的,因此next[4]=2,这个2是怎么来的呢?这个2不是因为j=2的那个B,⽽是因为j=1的那个A,因为j=1的A和j=3的A相匹配了,因此next[4] = 1 + 1,这才等于的2。
等号右边第⼀个1是j=1的1,第⼆个1是往右边⾛⼀位的1。
408中对kmp的考察KMP算法是一种用于字符串匹配的高效算法。
在408考试中,可能会出现对KMP算法的考察。
接下来将从算法原理、应用和相关问题等方面进行介绍。
KMP算法的核心思想是利用已经部分匹配的结果来避免不必要的重复比较,从而提高匹配效率。
该算法首先构建一个模式串的部分匹配表,在进行匹配时通过参考该表,根据已匹配的部分字符来确定下一次比较的位置。
具体来说,KMP算法中的部分匹配表是一个数组,其中存储了模式串的前缀子串的最长公共前后缀长度。
通过建立这个表,KMP算法能够在匹配过程中根据已经匹配的部分字符和部分匹配表中的值来决定下一次比较的位置,从而避免不必要的回退操作。
KMP算法广泛应用于字符串匹配问题,例如在文本编辑器中进行关键字搜索、网络爬虫中的网页关键字提取等场景。
其时间复杂度为O(n+m),其中n为文本串的长度,m为模式串的长度,相较于朴素的字符串匹配算法具有更高的效率。
在408考试中,对KMP算法的考察可能涉及以下内容:1. 理解KMP算法的原理和核心思想,包括构建部分匹配表和利用表进行匹配的过程。
2. 能够手动计算给定字符串和模式串的部分匹配表。
3. 理解KMP算法中的最长公共前后缀概念,以及如何根据已匹配的部分字符和部分匹配表来确定下一次比较的位置。
4. 能够实现KMP算法的代码,包括构建部分匹配表和利用表进行匹配的过程。
5. 分析KMP算法的时间复杂度和空间复杂度,了解其优势和适用性。
总之,对KMP算法的考察可能包括对原理、实现、应用和复杂度等方面的问题。
考生应该深入理解该算法的原理和应用,并熟练掌握其代码实现和分析能力。
kmp算法next函数详解KMP算法在介绍KMP算法之前,先介绍⼀下BF算法。
⼀.BF算法BF算法是普通的模式匹配算法,BF算法的思想就是将⽬标串S的第⼀个字符与模式串P的第⼀个字符进⾏匹配,若相等,则继续⽐较S的第⼆个字符和P的第⼆个字符;若不相等,则⽐较S的第⼆个字符和P的第⼀个字符,依次⽐较下去,直到得出最后的匹配结果。
举例说明:S: ababcababaP: ababaBF算法匹配的步骤如下i=0 i=1 i=2 i=3 i=4第⼀趟:a babcababa 第⼆趟:a b abcababa 第三趟:ab a bcababa 第四趟:aba b cababa 第五趟:abab c ababaa baba ab aba ab a ba aba b a abab aj=0 j=1 j=2 j=3 j=4(i和j回溯)i=1 i=2 i=3 i=4 i=3第六趟:a b abcababa 第七趟:ab a bcababa 第⼋趟:aba b cababa 第九趟:abab c ababa 第⼗趟:aba b cababaa baba a baba ab aba ab a ba a babaj=0 j=0 j=1 j=2(i和j回溯) j=0i=4 i=5 i=6 i=7 i=8第⼗⼀趟:abab c ababa 第⼗⼆趟:ababc a baba 第⼗三趟:ababca b aba 第⼗四趟:ababcab a ba 第⼗五趟:ababcaba b aa baba a baba ab aba ab a ba aba b aj=0 j=0 j=1 j=2 j=3i=9第⼗六趟:ababcabab aabab aj=4(匹配成功)代码实现:int BFMatch(char*s,char*p){int i,j;i=0;while(i<strlen(s)){j=0;while(s[i]==p[j]&&j<strlen(p)){i++;j++;}if(j==strlen(p))return i-strlen(p);i=i-j+1; //指针i回溯}return-1;}其实在上⾯的匹配过程中,有很多⽐较是多余的。
kmp算法pmt的值PMT的值是KMP算法中的一个重要概念,它代表了模式串中每个位置上的最长相同前缀后缀的长度。
在KMP算法中,PMT的值被用来确定当遇到不匹配字符时,模式串应该向右移动的位置,以提高匹配的效率。
KMP算法是一种字符串匹配算法,用于在一个文本串中查找一个模式串的出现位置。
与暴力匹配算法相比,KMP算法具有更高的效率。
PMT的值的计算是KMP算法中的关键步骤之一,下面将详细介绍PMT 的计算方法。
我们需要了解最长相同前缀后缀的概念。
对于一个字符串,它的前缀是指从开头到某个位置的子串,后缀是指从某个位置到末尾的子串。
例如,字符串"abcabc"的前缀有"","a","ab","abc",后缀有"","c","bc","abc"。
最长相同前缀后缀即是指一个字符串既是它的前缀,又是它的后缀,并且长度最长。
在KMP算法中,我们通过计算模式串的PMT数组来得到每个位置上的最长相同前缀后缀的长度。
具体计算过程如下:1. 初始化PMT数组,将第一个位置的值设为0。
2. 从第二个位置开始,依次计算每个位置上的PMT值。
3. 假设当前位置为i,PMT[i-1]表示前一个位置上的最长相同前缀后缀的长度。
我们需要判断当前位置的字符是否与PMT[i-1]位置上的字符相等。
- 如果相等,那么当前位置上的最长相同前缀后缀的长度就是PMT[i-1]+1。
- 如果不相等,我们可以利用PMT数组来找到一个更短的相同前缀后缀,并继续判断是否相等。
4. 重复步骤3,直到计算完所有位置上的PMT值。
通过上述步骤,我们就可以得到模式串的PMT数组。
在KMP算法中,当遇到不匹配字符时,我们可以利用PMT数组来确定模式串向右移动的位置。
具体操作如下:假设当前文本串的位置为i,模式串的位置为j。
KMP算法详解KMP 算法详解KMP 算法是⼀个⼗分⾼效的字符串查找算法,⽬的是在⼀个字符串 s 中,查询 s 是否包含⼦字符串 p,若包含,则返回 p 在 s 中起点的下标。
KMP 算法全称为 Knuth-Morris-Pratt 算法,由 Knuth 和 Pratt 在1974年构思,同年 Morris 也独⽴地设计出该算法,最终由三⼈于1977年联合发表。
举⼀个简单的例⼦,在字符串 s = ababcabababca 中查找⼦字符串 p = abababca,如果暴⼒查找,我们会遍历 s 中的每⼀个字符,若 s[i] = p[0],则向后查询p.length() 位是否都相等。
这种朴素的暴⼒的算法复杂度为O(m×n),其中m和n分别是 p 和 s 的长度。
KMP 算法可以⽅便地简化这⼀查询的时间复杂度,达到O(m+n)。
1. PMT 序列PMT 序列是 KMP 算法的核⼼,即 Partial Match Table(部分匹配表)。
举个例⼦:char a b a b a b c aindex01234567PMT00123401PMT 的值是字符串的前缀集合与后缀集合的交集中最长元素的长度。
PMT[0] = 0: 字符串 a 既没有前缀,也没有后缀;PMT[1] = 0: 字符串 ab 前缀集合为 {a},后缀集合为 {b},没有交集;PMT[2] = 1: 字符串 aba 前缀集合为 {a, ab},后缀集合为 {ba, a},交集为 {a},交集元素的最长长度为1;PMT[3] = 2: 字符串 abab 前缀集合为 {a, ab, aba},后缀集合为 {bab, ab, b},交集为 {ab},交集元素的最长长度为2;…… 以此类推。
2. 算法主体现在我们已经知道了 PMT 序列的含义,那么假设在 PMT 序列已经给定的情况下,如何加速字符串匹配算法?tar 存储 s 的下标,从 0 开始,若 tar > s.length() - 1,代表匹配失败;pos 存储 p 的下标,从 0 开始,若 s[tar] != p[pos],则 pos ⾛到下⼀个可能匹配的位置。
数据结构kmp算法例题KMP算法(Knuth-Morris-Pratt算法)是一种用于在一个主文本字符串S内查找一个模式字符串P的高效算法。
它利用了模式字符串内部的信息来避免在主字符串中不必要的回溯。
这种算法的关键在于构建一个部分匹配表,用于指示模式字符串中出现不匹配时的下一步匹配位置。
让我们来看一个KMP算法的例题:假设我们有一个主文本字符串S为,"ABC ABCDAB ABCDABCDABDE",模式字符串P为,"ABCDABD"。
我们要在主文本字符串S中查找模式字符串P的出现位置。
首先,我们需要构建模式字符串P的部分匹配表。
部分匹配表是一个数组,用于存储模式字符串中每个位置的最长相同前缀后缀的长度。
模式字符串P,"ABCDABD"部分匹配表:A B C D A B D.0 0 0 0 1 2 0。
接下来,我们使用KMP算法来在主文本字符串S中查找模式字符串P的出现位置。
算法的关键步骤如下:1. 初始化两个指针i和j,分别指向主文本字符串S和模式字符串P的起始位置。
2. 逐个比较S[i]和P[j],如果相等,则继续比较下一个字符;如果不相等,则根据部分匹配表调整j的位置。
3. 如果j达到了模式字符串P的末尾,则说明找到了一个匹配,记录匹配位置,并根据部分匹配表调整j的位置。
4. 继续比较直到遍历完主文本字符串S。
根据上述步骤,我们可以在主文本字符串S中找到模式字符串P的所有出现位置。
总结来说,KMP算法通过构建部分匹配表和利用匹配失败时的信息来避免不必要的回溯,从而实现了高效的字符串匹配。
希望这个例题能帮助你更好地理解KMP算法的原理和应用。
KMP字符串模式匹配详解KMP字符串模式匹配通俗点说就是一种在一个字符串中定位另一个串的高效算法。
简单匹配算法的时间复杂度为O(m*n);KMP匹配算法。
可以证明它的时间复杂度为O(m+n).。
一.简单匹配算法先来看一个简单匹配算法的函数:int Index_BF ( char S [ ], char T [ ], int pos ){/* 若串S 中从第pos(S 的下标0≤pos<StrLength(S))个字符起存在和串T 相同的子串,则称匹配成功,返回第一个这样的子串在串S 中的下标,否则返回-1 */int i = pos, j = 0;while ( S[i+j] != '\0'&& T[j] != '\0')if ( S[i+j] == T[j] )j ++; // 继续比较后一字符else{i ++; j = 0; // 重新开始新的一轮匹配}if ( T[j] == '\0')return i; // 匹配成功返回下标elsereturn -1; // 串S中(第pos个字符起)不存在和串T相同的子串} // Index_BF此算法的思想是直截了当的:将主串S中某个位置i起始的子串和模式串T相比较。
即从j=0 起比较S[i+j] 与T[j],若相等,则在主串S 中存在以i 为起始位置匹配成功的可能性,继续往后比较( j逐步增1 ),直至与T串中最后一个字符相等为止,否则改从S串的下一个字符起重新开始进行下一轮的"匹配",即将串T向后滑动一位,即i 增1,而j 退回至0,重新开始新一轮的匹配。
例如:在串S=”abcabcabdabba”中查找T=” abcabd”(我们可以假设从下标0开始):先是比较S[0]和T[0]是否相等,然后比较S[1] 和T[1]是否相等…我们发现一直比较到S[5] 和T[5]才不等。
如图:当这样一个失配发生时,T下标必须回溯到开始,S下标回溯的长度与T 相同,然后S下标增1,然后再次比较。
如图:这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。
如图:这次立刻发生了失配,T下标又回溯到开始,S下标增1,然后再次比较。
如图:又一次发生了失配,所以T下标又回溯到开始,S下标增1,然后再次比较。
这次T中的所有字符都和S中相应的字符匹配了。
函数返回T在S中的起始下标3。
如图:二. KMP匹配算法还是相同的例子,在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,当第一次搜索到S[5] 和T[5]不等后,S下标不是回溯到1,T下标也不是回溯到开始,而是根据T中T[5]==’d’的模式函数值(next[5]=2,为什么?后面讲),直接比较S[5] 和T[2]是否相等,因为相等,S和T的下标同时增加;因为又相等,S和T的下标又同时增加。
最终在S中找到了T。
如图:KMP匹配算法和简单匹配算法效率比较,一个极端的例子是:在S=“AAAAAA…AAB“(100个A)中查找T=”AAAAAAAAAB”, 简单匹配算法每次都是比较到T的结尾,发现字符不同,然后T的下标回溯到开始,S的下标也要回溯相同长度后增1,继续比较。
如果使用KMP匹配算法,就不必回溯.对于一般文稿中串的匹配,简单匹配算法的时间复杂度可降为O (m+n),因此在多数的实际应用场合下被应用。
KMP算法的核心思想是利用已经得到的部分匹配信息来进行后面的匹配过程。
看前面的例子。
为什么T[5]==’d’的模式函数值等于2(next[5]=2),其实这个2表示T[5]==’d’的前面有2个字符和开始的两个字符相同,且T[5]==’d’不等于开始的两个字符之后的第三个字符(T[2]=’c’).如图:也就是说,如果开始的两个字符之后的第三个字符也为’d’,那么,尽管T[5]==’d’的前面有2个字符和开始的两个字符相同,T[5]==’d’的模式函数值也不为2,而是为0。
前面我说:在S=”abcabcabdabba”中查找T=”abcabd”,如果使用KMP匹配算法,当第一次搜索到S[5] 和T[5]不等后,S下标不是回溯到1,T下标也不是回溯到开始,而是根据T中T[5]==’d’的模式函数值,直接比较S[5] 和T[2]是否相等。
为什么可以这样?刚才我又说:“(next[5]=2),其实这个2表示T[5]==’d’的前面有2个字符和开始的两个字符相同”。
请看图:因为,S[4] ==T[4],S[3] ==T[3],根据next[5]=2,有T[3]==T[0],T[4] ==T[1],所以S[3]==T[0],S[4] ==T[1](两对相当于间接比较过了),因此,接下来比较S[5] 和T[2]是否相等。
有人可能会问:S[3]和T[0],S[4] 和T[1]是根据next[5]=2间接比较相等,那S[1]和T[0],S[2] 和T[0]之间又是怎么跳过,可以不比较呢?因为S[0]=T[0],S[1]=T[1],S[2]=T[2],而T[0] != T[1], T[1] != T[2],==> S[0] != S[1],S[1] != S[2],所以S[1] != T[0],S[2] != T[0]. 还是从理论上间接比较了。
有人疑问又来了,你分析的是不是特殊轻况啊。
假设S不变,在S中搜索T=“abaabd”呢?答:这种情况,当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=-1,意思是S[2]已经和T[0] 间接比较过了,不相等,接下来去比较S[3]和T[0]吧。
假设S不变,在S中搜索T=“abbabd”呢?答:这种情况当比较到S[2]和T[2]时,发现不等,就去看next[2]的值,next[2]=0,意思是S[2]已经和T[2]比较过了,不相等,接下来去比较S[2]和T[0]吧。
假设S=”abaabcabdabba”在S中搜索T=“abaabd”呢?答:这种情况当比较到S[5]和T[5]时,发现不等,就去看next[5]的值,next[5]=2,意思是前面的比较过了,其中,S[5]的前面有两个字符和T的开始两个相等,接下来去比较S[5]和T[2]吧。
总之,有了串的next值,一切搞定。
那么,怎么求串的模式函数值next[n]呢?(本文中next值、模式函数值、模式值是一个意思。
)三. 怎么求串的模式值next[n]定义:(1)next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。
(2)next[j]= -1 意义:模式串T中下标为j的字符,如果与首字符相同,且j的前面的1—k个字符与开头的1—k个字符不等(或者相等但T[k]==T[j])(1≤k<j)。
如:T=”abCabCad” 则next[6]=-1,因T[3]=T[6] (3)next[j]=k 意义:模式串T中下标为j的字符,如果j的前面k个字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。
即T[0]T[1]T[2]。
T[k-1]==T[j-k]T[j-k+1]T[j-k+2]…T[j-1]且T[j] != T[k].(1≤k<j);]=0 意义:除(1)(2)(3)的其他情况。
举例:01)求T=“abcac”的模式函数的值。
next[0]= -1 根据(1)next[1]=0 根据(4) 因(3)有1<=k<j;不能说,j=1,T[j-1]==T[0]next[2]=0 根据(4) 因(3)有1<=k<j;(T[0]=a)!=(T[1]=b)next[3]= -1 根据(2)next[4]=1 根据(3) T[0]=T[3] 且T[1]=T[4]即下标01234T a b c a cnext-100-11若T=“abcab”将是这样:下标01234T a b c a bnext-100-10为什么T[0]==T[3],还会有next[4]=0呢, 因为T[1]==T[4], 根据(3)”且T[j] != T[k]”被划入(4)。
02)来个复杂点的,求T=”ababcaabc” 的模式函数的值。
next[0]= -1 根据(1)next[1]=0 根据(4)next[2]=-1 根据(2)next[3]=0 根据(3) 虽T[0]=T[2] 但T[1]=T[3] 被划入(4)next[4]=2 根据(3) T[0]T[1]=T[2]T[3] 且T[2] !=T[4]next[5]=-1 根据(2)next[6]=1 根据(3) T[0]=T[5] 且T[1]!=T[6]next[7]=0 根据(3) 虽T[0]=T[6] 但T[1]=T[7] 被划入(4)next[8]=2 根据(3) T[0]T[1]=T[6]T[7] 且T[2] !=T[8]即下标012345678T a b a b c a a b cnext-10-102-1102只要理解了next[3]=0,而不是=1,next[6]=1,而不是= -1,next[8]=2,而不是= 0,其他的好象都容易理解。
03)来个特殊的,求T=”abCabCad” 的模式函数的值。
下标01234567T a b C a b C a dnext-100-100-14next[5]= 0 根据(3) 虽T[0]T[1]=T[3]T[4],但T[2]==T[5]next[6]= -1 根据(2) 虽前面有abC=abC,但T[3]==T[6]next[7]=4 根据(3) 前面有abCa=abCa,且T[4]!=T[7]若T[4]==T[7],即T=” adCadCad”,那么将是这样:next[7]=0, 而不是= 4,因为T[4]==T[7].下标01234567T a d C a d C a dnext-100-100-10如果你觉得有点懂了,那么练习:求T=”AAAAAAAAAAB” 的模式函数值,并用后面的求模式函数值函数验证。
意义:next 函数值究竟是什么含义,前面说过一些,这里总结。
设在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函数值next[n], 1.next[n]= -1 表示S[m]和T[0]间接比较过了,不相等,下一次比较S[m+1] 和T[0]2.next[n]=0 表示比较过程中产生了不相等,下一次比较S[m] 和T[0]。
3.next[n]= k >0 但k<n, 表示,S[m]的前k个字符与T中的开始k个字符已经间接比较相等了,下一次比较S[m]和T[k]相等吗?4.其他值,不可能。