BM算法的效率是KMP算法的3-5倍,是一种效率高,构思巧妙的字符串匹配算法。
与基于前缀比较的暴力匹配算法以及KMP算法不同,BM算法采用基于后缀的比较方法,在BM算法中,包含了两个并行的比较方法:1.坏字符算法;2.好后缀算法。算法的核心在于,通过并行的坏字符与好后缀算法,计算出每次后移的最大位移(不超过模式串本身大小)。
算法的开始将待匹配字符串(textString)与模式串(patString)从头部进行对齐。自尾部开始进行字符比较,若尾部比较失败,则可通过一次比较确定匹配失败,进行位移操作。
如图,当模式串的E与A进行比较失败时,即可确定此次匹配失败,进入移位操作,通过坏字符算法与好后缀算法分别获取位移值,取两者中的最大值进行位移操作。下面,将详细对这两个算法进行分析。
坏字符算法:
当待匹配串中的当前字符与模式串中对应位置的字符串不一致时,当前字符即为坏字符,此时存在两种情况:1.坏字符不存在于模式串中;2.坏字符在模式串中存在,且最近一次出现位置为lastpostion(注:本文均采用数组记数方式,从0开始);
依据公式: 位移数(Shift) = 坏字符在当前匹配串中的位置(position) - lastposition;
第一种情况下,坏字符不存在于模式串中,则记lastposition为-1,此时位移数即为当前的position + 1,亦即将整个patString移至当前坏字符的下一位进行匹配:
此时状态如上图所示,依然进行尾部匹配,此时为第二种情况,坏字符P存在于模式串中,position为6(与当前patString中匹配字符的位置对应),lastposition为4,则
Shift = 6 - 4 = 2;
此时状态如下:
在接下来的匹配过程中,E,LE,PLE,MPLE这类尾部匹配的字符串均为好后缀(Good suffix).
好后缀算法:
Shift = 好后缀的位置 - 该后缀在搜索词中上一次出现的位置(last_position)
在比较时,由于算法本身采用后缀比较法,采用好后缀的最后字符的位置作为标记位置,则下一步状态如图:
Shift = postion of E(6) - last position of E(0) = 6;
到这里整个算法流程已经比较明确了,经过重复,后面的结果如下:
继续比较,发现坏字符P,按照公式进行移位:
Shift = 6 - 4 = 2;
自尾部比较,发现匹配,则返回结果,如当前搜索串在textString中的位置,进行标记,算法分析部分至此结束。