关于KMP算法和BM算法的理解
KMP讲解

有了覆盖函数,那么实现kmp算法就是很简单的了,我们的原则还是从左向右匹配,但是当失配发生时,我们不用把target_index向回移动,target_index前面已经匹配过的部分在pattern自身就能体现出来,只要动pattern_index就可以了。
当发生在j长度失配时,只要把pattern向右移动j-overlay(j)长度就可以了。
说了这么半天那么这种方法是什么呢,这种方法是就大名鼎鼎的确定的有限自动机(Deterministic finite state automaton DFA),DFA可识别的文法是3型文法,又叫正规文法或是正则文法,既然可以识别正则文法,那么识别确定的字串肯定不是问题(确定字串是正则式的一个子集)。对于如何构造DFA,是有一个完整的算法,这里不做介绍了。在识别确定的字串时使用DFA实在是大材小用,DFA可以识别更加通用的正则表达式,而用通用的构建DFA的方法来识别确定的字串,那这个overhead就显得太大了。
{
index = overlay_value[index];
}
if(pattern[index+1]==pattern[i])
{
overlay_value[i] = index +1;
KMP 算法可在O(n+m)时间内完成全部的串的模式匹配工作。
ok,最后给出KMP算法实现的c++代码:
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int kmp_find(const string& target,const string& pattern)
文本匹配算法的优化策略与应用

文本匹配算法的优化策略与应用随着信息爆炸时代的到来,人们需要处理和理解大量的文本数据。
文本匹配算法的优化策略与应用因此变得尤为重要。
本文将探讨一些常见的文本匹配算法,以及如何优化这些算法以提高其效率和准确性。
一、基础算法介绍1.1 精确匹配算法精确匹配算法是最简单的文本匹配算法之一,它通过逐个比较文本中的字符来确定匹配程度。
这种算法的优点是简单易懂,但其缺点是效率较低,尤其是在处理大规模文本数据时。
1.2 KMP算法KMP算法是一种改进的文本匹配算法,它通过预处理模式串,利用已经匹配过的信息来减少不必要的比较次数。
KMP算法在处理大规模文本数据时具有较高的效率,但其空间复杂度较高。
1.3 BM算法BM算法是一种基于后缀匹配的文本匹配算法,它通过从模式串末尾开始匹配,利用模式串中的字符出现位置来快速跳过不匹配的字符。
BM算法在处理大规模文本数据时具有较高的效率和较低的空间复杂度。
二、优化策略2.1 基于索引的优化基于索引的优化策略是通过建立文本的索引结构,提高匹配算法的效率。
常见的索引结构有倒排索引、前缀树和后缀树等。
这些索引结构可以帮助我们快速定位关键词的位置,从而提高匹配的速度。
2.2 基于语义的优化基于语义的优化策略是通过理解文本的语义信息,提高匹配算法的准确性。
常见的语义分析方法有词向量模型和主题模型等。
这些方法可以帮助我们更好地理解文本的含义,从而提高匹配的准确性。
2.3 基于机器学习的优化基于机器学习的优化策略是通过训练模型,提高匹配算法的准确性和泛化能力。
常见的机器学习算法有支持向量机、决策树和深度学习等。
这些算法可以通过学习大量的文本数据,自动提取特征并进行匹配。
三、应用场景3.1 文本检索文本检索是文本匹配算法的一种重要应用场景。
通过优化算法和建立索引结构,可以提高文本检索的速度和准确性。
例如,在搜索引擎中,我们可以根据用户输入的关键词,快速找到相关的文本信息。
3.2 自然语言处理自然语言处理是另一个重要的文本匹配应用场景。
关键字匹配函数

关键字匹配函数
在计算机科学中,关键字匹配函数通常用于在文本或数据集中查找特定的关键字或模式。
这些函数可以用于各种应用,如搜索引擎、数据挖掘、自然语言处理等。
以下是一些常见的关键字匹配函数的示例:
1.朴素字符串匹配(Naive String Matching):这是最简单的关键字匹配算法,它逐个比较文本中的每个字符与目标关键字。
时间复杂度为O(n),其中n是文本的长度。
2.KMP算法(Knuth-Morris-Pratt算法):KMP算法是一种改进的字符串匹配算法,它通过预处理目标关键字来减少比较次数。
时间复杂度为O(n+m),其中n是文本的长度,m是目标关键字的长度。
3.BM算法(Boyer-Moore算法):BM算法也是一种改进的字符串匹配算法,它通过构建坏字符规则和好后缀规则来减少比较次数。
时间复杂度为O(n+m)。
4.AC自动机(Aho-Corasick算法):AC自动机是一种多模式字符串匹配算法,它通过构建Trie树和失配指针来同时匹配多个关键字。
时间复杂度为O(m),其中m是关键字的数量。
5.KMP算法的变种:有一些基于KMP算法的变种,如Sunday算法、逆Sunday算法等,它们通过不同的方式来预处理目标关键字,以减少比较次数。
这些函数都有各自的优点和缺点,选择哪种函数取决于具体的应用场景和需求。
例如,对于小文本和短关键字,朴素字符串匹配可
能足够快;对于大文本和长关键字,KMP、BM或AC自动机可能更有效。
kmp算法概念

kmp算法概念KMP算法概念KMP算法是一种字符串匹配算法,它的全称是Knuth-Morris-Pratt 算法。
该算法通过预处理模式串,使得在匹配过程中避免重复比较已经比较过的字符,从而提高了匹配效率。
一、基本思想KMP算法的基本思想是:当模式串与文本串不匹配时,不需要回溯到文本串中已经比较过的位置重新开始匹配,而是利用已知信息跳过这些位置继续匹配。
这个已知信息就是模式串自身的特点。
二、next数组1.定义next数组是KMP算法中最核心的概念之一。
它表示在模式串中当前字符之前的子串中,有多大长度的相同前缀后缀。
2.求解方法通过观察模式串可以发现,在每个位置上出现了相同前缀和后缀。
例如,在模式串“ABCDABD”中,第一个字符“A”没有任何前缀和后缀;第二个字符“B”的前缀为空,后缀为“A”;第三个字符“C”的前缀为“AB”,后缀为“B”;第四个字符“D”的前缀为“ABC”,后缀为“AB”;第五个字符“A”的前缀为“ABCD”,后缀为“ABC”;第六个字符“B”的前缀为“ABCDA”,后缀为“ABCD”;第七个字符“D”的前缀为“ABCDAB”,后缀为“ABCDA”。
根据上述观察结果,可以得到一个求解next数组的方法:(1)next[0]=-1,next[1]=0。
(2)对于i=2,3,...,m-1,求解next[i]。
①如果p[j]=p[next[j]],则next[i]=next[j]+1。
②如果p[j]≠p[next[j]],则令j=next[j],继续比较p[i]和p[j]。
③重复执行步骤①和步骤②,直到找到满足条件的j或者j=-1。
(3)通过上述方法求解出所有的next值。
三、匹配过程在匹配过程中,文本串从左往右依次与模式串进行比较。
如果当前字符匹配成功,那么继续比较下一个字符;否则利用已知信息跳过一些位置继续进行匹配。
具体地:(1)如果当前字符匹配成功,则i和j都加1。
(2)如果当前字符匹配失败,则令j=next[j]。
BF算法KMP算法BM算法

BF算法KMP算法BM算法BF算法(Brute-Force Algorithm)是一种简单直接的字符串匹配算法,也称为朴素算法。
BF算法的基本思想是从主串的第一个字符开始,每次移动一个字符,然后和模式串进行逐个字符比较,如果不匹配,则继续下一个位置的比较。
如果字符匹配,则比较下一个字符,直到找到完全匹配的子串或者主串遍历结束。
BF算法的时间复杂度为O(m*n),其中m和n分别为主串和模式串的长度。
当主串和模式串的长度较小时,BF算法是一个简单高效的字符串匹配算法。
然而,当主串和模式串的长度非常大时,BF算法的效率会非常低下。
KMP算法(Knuth-Morris-Pratt Algorithm)是一种改进的字符串匹配算法。
KMP算法的核心思想是利用已经匹配过的部分信息来避免不必要的字符比较。
KMP算法通过构建一个跳转表(也称为失配函数),记录当前位置之前的字符中可能出现的最大公共前后缀长度。
根据跳转表的信息,在模式串和主串不匹配时,可以直接跳过一些字符,继续比较下一个字符。
KMP算法的时间复杂度为O(m+n),其中m和n分别为主串和模式串的长度。
KMP算法在主串长度较大时,相对于BF算法有较高的效率。
它的空间复杂度为O(k),其中k为模式串的长度,用于存储跳转表。
BM算法(Boyer-Moore Algorithm)是一种更为高效的字符串匹配算法。
BM算法的核心思想是尽可能地跳过更多的字符,而不是每次只移动一个字符。
BM算法借助两个启发式规则(坏字符规则和好后缀规则)来确定移动的步长。
坏字符规则根据字符在模式串中的位置,找到离坏字符最近的下标位置,从而确定移动的步长;好后缀规则根据已经匹配的后缀子串,找到离该子串最近的下标位置,从而确定移动的步长。
BM算法的时间复杂度为O(m+n),其中m和n分别为主串和模式串的长度。
BM算法在处理文本串相对固定的情况下有较高的效率,但是在模式串较短,主串较长的情况下,BM算法并不一定比KMP算法更高效。
字符串匹配问题的算法步骤

字符串匹配问题的算法步骤字符串匹配是计算机科学中常见的问题,主要用于确定一个字符串是否包含另一个字符串。
解决这个问题的算法可以分为暴力匹配算法、Knuth-Morris-Pratt(KMP)算法和Boyer-Moore(BM)算法等。
暴力匹配算法是最简单的一种方法。
它的基本思想是从主串的第一个字符开始,依次和模式串的每个字符进行比较,直到找到一个字符不匹配为止。
如果找到了不匹配的字符,则将主串的指针后移一位,重新开始匹配。
如果匹配成功,模式串的指针向后移一位,主串的指针也向后移一位,继续匹配。
这个过程一直进行下去,直到模式串的指针到达模式串的末尾,或者找到了一个匹配的子串。
尽管暴力匹配算法很简单,但是它的时间复杂度较高,为O(m*n),其中m是主串的长度,n是模式串的长度。
当主串和模式串很长时,暴力匹配算法的效率就会很低。
为了提高字符串匹配的效率,有很多其他的算法被提出。
其中比较著名的是KMP算法和BM算法。
KMP算法的核心思想是,当发生不匹配的情况时,不需要回溯主串的指针,而是通过已经匹配的部分字符的信息,将模式串的指针移动到一个新的位置,从而避免了不必要的比较。
具体来说,KMP算法在匹配的过程中,通过建立一个部分匹配表(Partial Match Table),来记录模式串中每个位置的最长前缀后缀的长度。
当发生不匹配的情况时,根据部分匹配表的信息,可以将模式串的指针直接移动到下一个可能匹配的位置。
BM算法是一种基于启发式的匹配算法,它的核心思想是从模式串的尾部开始匹配,并根据已经匹配的部分字符的信息,跳跃式地移动模式串的指针。
具体来说,BM算法分别构建了坏字符规则和好后缀规则。
坏字符规则用于处理主串中与模式串不匹配的字符,找到最右边的该字符在模式串中的位置,并移动模式串的指针到对齐该字符。
好后缀规则用于处理主串中与模式串匹配的部分,找到最右边的该部分在模式串中的位置,并移动模式串的指针到对齐该部分。
BM算法讲解

由于毕业设计(入侵检测)的需要,这两天仔细研究了BM模式匹配算法,稍有心得,特此记下。
首先,先简单说明一下有关BM算法的一些基本概念。
BM算法是一种精确字符串匹配算法(区别于模糊匹配)。
BM算法采用从右向左比较的方法,同时应用到了两种启发式规则,即坏字符规则和好后缀规则,来决定向右跳跃的距离。
BM算法的基本流程: 设文本串T,模式串为P。
首先将T与P进行左对齐,然后进行从右向左比较,如下图所示:若是某趟比较不匹配时,BM算法就采用两条启发式规则,即坏字符规则和好后缀规则,来计算模式串向右移动的距离,直到整个匹配过程的结束。
下面,来详细介绍一下坏字符规则和好后缀规则。
首先,诠释一下坏字符和好后缀的概念。
请看下图:图中,第一个不匹配的字符(红色部分)为坏字符,已匹配部分(绿色)为好后缀。
1)坏字符规则(Bad Character):在BM算法从右向左扫描的过程中,若发现某个字符x不匹配,则按如下两种情况讨论:i. 如果字符x在模式P中没有出现,那么从字符x开始的m个文本显然不可能与P匹配成功,直接全部跳过该区域即可。
ii. 如果x在模式P中出现,则以该字符进行对齐。
用数学公式表示,设Skip(x)为P右移的距离,m为模式串P的长度,max(x)为字符x在P中最右位置。
例1:下图红色部分,发生了一次不匹配。
计算移动距离Skip(c) = 5 - 3 = 2,则P向右移动2位。
移动后如下图:2)好后缀规则(Good Suffix):若发现某个字符不匹配的同时,已有部分字符匹配成功,则按如下两种情况讨论:i. 如果在P中位置t处已匹配部分P'在P中的某位置t'也出现,且位置t'的前一个字符与位置t的前一个字符不相同,则将P右移使t'对应t方才的所在的位置。
ii. 如果在P中任何位置已匹配部分P'都没有再出现,则找到与P'的后缀P''相同的P的最长前缀x,向右移动P,使x对应方才P''后缀所在的位置。
字符串快速匹配算法

字符串快速匹配算法字符串快速匹配算法,指的是在一个文本串中查找一个模式串的过程。
在计算机科学中,字符串匹配是一种基本的问题,在许多应用中都有广泛的应用,比如:文本编辑器、数据压缩、网络安全等等。
传统的字符串匹配算法,如朴素匹配算法和KMP算法,虽然可行,但是时间复杂度较高,对于大规模数据匹配效率较低。
为了提高字符串匹配效率,人们提出了许多快速匹配算法,如BM算法、Sunday算法、AC自动机等等。
BM算法是一种基于后缀匹配思想的快速字符串匹配算法,它的核心思想是在匹配的过程中,根据模式串的后缀字符来确定跳过的字符数。
BM算法的时间复杂度为O(n/m),其中n为文本串的长度,m为模式串的长度,因此它可以在较短的时间内完成匹配任务。
BM算法的实现过程较为复杂,但是由于其高效性,被广泛应用于实际工程中。
Sunday算法是一种基于贪心思想的快速字符串匹配算法,它的核心思想是在匹配的过程中,每次从模式串的末尾开始比较,如果匹配成功,则直接返回匹配位置,否则通过预处理模式串中的字符来确定跳过的字符数。
Sunday算法的时间复杂度为O(n/m),其中n 为文本串的长度,m为模式串的长度,因此它也可以在较短的时间内完成匹配任务。
Sunday算法的实现过程相对简单,适用于短模式串和长文本串的匹配。
AC自动机是一种基于字典树的快速字符串匹配算法,它的核心思想是将所有模式串构建成一个AC自动机,然后在文本串中进行匹配。
AC自动机的时间复杂度为O(n+k),其中n为文本串的长度,k为模式串的总长度,因此它可以在非常短的时间内完成匹配任务。
AC 自动机的实现过程比较复杂,但是由于其高效性,被广泛应用于网络安全和搜索引擎等领域。
除了上述几种算法,还有许多其他的快速字符串匹配算法,如RK 算法、Trie树、后缀树等等。
这些算法各有特点,适用于不同的场景和数据类型。
在实际应用中,我们需要根据具体的需求和数据特征,选择合适的算法来完成字符串匹配任务。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
移动规则我理解应该是上面的5条,坏字符规则2条,好后缀规则3条。对于好后缀规则1,我想再用图解释一下:
3
2
1
t
上图指的是模式串P,假设下表从1开始,由图可知,P[1…3]、P[7…9]、P[13…15]、P[20…22]和后缀P[26…28]相匹配,但我们首先要选个最大,首先考虑的是P[20…22]子串,但因为P[19]和P[25]相同,所以不符合条件。则P[13…15]符合条件。(这里有个需要注意的地方,就是如果假设只有P[1…3]和后缀P[26…28]相匹配,此时需要判断P[25]和P[0],因为P[0]是不存在的,所以认为P[25]和P[0]是不等的,即P[1…3]满足条件)
这个表看似神奇,实际从原理上讲并不复杂,对于模式串而言,其前缀字符串,有可能也是模式串中的非前缀子串,这个问题我称之为前缀包含问题。以模式串abcabcacab为例,其前缀abca,正好也是模式串的一个子串abc(abca)cab,所以当目标串与模式串执行匹配的过程中,如果直到第8个字符才匹配失败,同时也意味着目标串当前字符之前的4个字符,与模式串的前4个字符是相同的,所以当模式串向后移动的时候,可以直接将模式串的第5个字符与当前字符对齐,执行比较,这样就实现了模式串一次性向前跳跃多个字符。这里只是一个模式串移动的思想。
i.如果字符x在模式P中没有出现,那么含有字符x的m个文本显然不可能与P匹配成功,直接全部跳过该区域即可(即将模式串的第一个字符与X下一个位置字符比较)。
ii.如果x在模式P中出现,则将该坏字符x与模式串中从右向左最早出现字符x的位置对应。
所谓的坏字符移动规则,就是一个表,根据原论文,命名为delta1。其以目标串输入字符集的所有字符作为索引,每个输入字符c对应着一个值,表示如果目标串的当前位置字符c与模式串匹配失败,那么目标串当前位置应该可以向前滑动的步数(注意这里说的是“目标串当前位置”的滑动)。
如果P[j] !=P[f(j)],next[j] = f(j);
如果P[j] =P[f(j)],next[j] = next[f(j)];
当要求f(9)时,f(8)和next[8]已经可以得到,此时我们可以考察P[next[8]],根据前面对于next值的计算方式,我们知道P[8] !=P[next[8]]。我们的目的是要找到P[9]的包含前缀,而P[8] !=P[5],P[1...5]!=P[4...8]。我们继续考察P[next[5]]。如果P[8] =P[next[5]],假设next[5] =2,说明P[1] =P[4]= P[7],且P[2] =P[8],此时对于P[9]而言,就有P[1...2]=P[7...8],我们就找到了f(9) =3。这里我们考察的是P[next[j]],而不是P[f(j)],这是因为对于next[]而言,P[j] !=P[next[j]],而对于f()而言,P[j]与P[f(j)]不一定不相等,而我们的目的就是要在P[j] !=P[f(j)]的情况下,解决f(j+1)的问题,所以使用next[j]向前回溯,是正确的。
网上对于BM算法思想的分析真的是各种理解,其中有两篇博客我觉得写的比较清楚,值得参考学习,在文章结尾给出链接。
针对坏字符和好后缀,给出了两个表,坏字符表和好后缀表,匹配过程中的移动要借助着两个表,对于这两个表我给出自己的理解。
1.坏字符规则
在BM算法从右向左扫描的过程中,若发现某个字符x(这个字符X是指目标串中的字符)不匹配,则按如下两种情况讨论:
3.关于模式串的移动
很多文章中都说匹配过程中对模式串进行移动,但这里很多时候说的都不清楚,或者我感觉前后是矛盾的。
有模式串P和目标串T,发现不匹配,
根据下面说明的5条移动规则可知,移动后结果如下:
针对模式串P而言,模式串向后移动的距离为3,对于目标串当前位置而言,向后移动的距离确实6。而针对这个问题,很多文章没有给出详细的说明,这两个概念混淆不清,一会说模式串移动,其实给出的值却是针对目标串当前位置的。
说下如何根据next[i]的值进行移动。如果目标字符串匹配失败字符对应的是模式串中第i个字符,则将模式串向后移动i–next[i]后继续进行匹配。
BM算法
而BM算法在移动模式串的时候是从左到右,而进行比较的时候是从右到左的,基本框架是:
j = 0;
while (j <= strlen(T) - strlen(P)) {
其实利用之前的结果,我们还可以得到更多的信息。还是以P[8]为例。f(8) = 5,P[1...4]=P[4...7],此时我们需要关注P[8],如果P[8] !=P[5],那么在匹配算法如果匹配到P[8]才失败,此时就可以将输入字符T[n]与P[f(8)] =P[5]对齐,再向后依次执行匹配,所以此时的next[8] = f(8)。而如果P[8] =P[5],那么P[1...5]=P[4...8],如果T[n]与P[8]匹配失败,那么同时也意味着T[n-5...n]!=P[4...8],那么将T[n]与P[5]对齐,T[n-5...n]也必然不等于P[1...5],此时我们需要关注f(5) = 2,这意味着P[1] =P[4],因为P[1...4]=P[4...7],所以P[4]=P[7]=P[1],此时我们再来比较P[8]与P[2],如果P[8] !=P[2],就可以将T[n]与P[2],然后比较二者是否相等,此时next[8] = next[5] = f(2)。如果P[8] =P[2],那么还需要考察P[f(2)],直到回溯到模式串头部为止。下面给出根据f(j)值求next[j]的递推公式:
上图可以很好的说明坏字符和好后缀,即后缀匹配过程中,已匹配的部分为好后缀,第一个不匹配字符为坏字符。很多理解对于坏字符和好后缀就停留在这里了,其实我觉得这里还有一个很重要的概念,就是坏字符和好后缀是相对于谁而言的(是针对T还是P的呢)。从我个人的理解(不一定是正确的)看,坏字符是相对于目标串T的,也就是指的上图中的b,而不是模式串中的c。好后缀是相对于模式串P的,也就是指的上图中的下面的aba。至于为什么这样理解,我觉得这样对于后面理解模式串的移动是有帮助的。
如何以较小的代价计算KMP算法中所用到的跳转表next,是算法的核心问题。这里我们引入一个概念f(j),其含义是,对于模式串的第j个字符P[j],f(j)是所有满足使P[1...k-1] =P[j-(k-1)...j - 1](k < j)成立的k的最大值。还是以模式串abcabcacab(下标从1开始)为例,当处理到P[8] = 'c'时,我们想找到'c'前面的k-1个字符,使得P[1...k-1] =P[8-(k-1)...7],这里我们可以使用一个笨法,让k-1从1到6递增,然后依次比较,直到找到最大值的k为止。但是这样的方法比较低效,而且没有充分利用到之前的计算结果。在我们处理P[8] = 'c'之前,P[7] = 'a'的最大前缀包含问题已经解决,f(7) = 4,也就是说,P[4...6] =P[1...3],此时我们可以比较P[7]与P[4],如果P[4]=P[7],对于P[8]而言,说明P[1...4]=P[4...7],此时,f(8) = f(7) + 1 = 5。再以P[9]为例,f(8) = 5,P[1...4]=P[4...7],但是P[8] !=P[5],所以P[1...5]!=P[4...8],此时无法利用f(8)的值直接计算出f(9)。
2.好后缀移动规则
好后缀移动规则是BM算法的核心,这里分三种情况讨论:
i.如果在P中位置t处已匹配部分P'在P中的某位置t'也出现,且位置t'的前一个字符与位置t的前一个字符不相同,则将P右移使t'对应t方才的所在的位置。如果同时有多个t'出现时,选择最大的那个t'。
ii.如果在P中任何位置已匹配部分P'都没有再出现,则找到与P'的后缀P''相同的P的最长前缀x(这里是前缀不是子串),向右移动P,使x对应方才P''后缀所在的位置。
现在,我们来总结一下next[j]和f(j)的关系,next[j]是所有满足P[1...k - 1] =P[(j - (k - 1))...j -1](k < j),且P[k] !=P[j]的k中,k的最大值。而f(j)是满足P[1...k - 1] =P[(j - (k - 1))...j -1](k < j)的k中,k的最大值。还是以上例的模式来说,对于第7个元素,其f(j) = 4,说明P[7]的前3个字符与模式的前缀3相同,但是由于P[7] =P[4],所以next[7] != 4。
首先有几个概念要先说清楚,我发现很多文章里面完全没有说或者只说了部分。
1.目标串和模式串
目标串是我们需要在其中查找匹配的字符串,一般用T(T)表示,模式串是给定的需要匹配的字符串,一般用P(P)表示。EX:T=abababaabab,P=acaba,我们的任务是判断在T中是否有和P相匹配的字符串。
2.坏字符和好后缀
坏字符表的定义为,对于输入字符集合中的字符c,如果c不在模式串中,则delta1[c]= patlen(模式串的长度),如果c在模式串中,则delta1[c]=j-i,其中,j是模式串最末元素的索引值,i是字符c在模式串中最右出现的位置。用数学公式表示,设m为模式串P的长度,max(x)为字符x在P中最右位置。
那为什么要分清这两个概念呢,其实用哪个都是一样的,关键是在匹配过程中概念上要统一。在很多的匹配情况中,好后缀和坏字符是同时出现的,这个时候就要运用坏字符规则和好后缀规则,从中找一个值大的,进行更大的移动。如果坏字符规则得到的数值是针对模式串的,好后缀规则得到的数值是针对目标串当前位置的话,那么算法将得不到正确解。下面关于BM算法的移动讨论都是针对目标串当前位置的。