grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)

时间:2020-12-20 23:31:49

这篇长文历时近两天终于完成了,前两天帮网站翻译一篇文章“为什么GNU grep如此之快?”,里面提及到grep速度快的一个重要原因是使用了Boyer-Moore算法作为字符串搜索算法,兴趣之下就想了解这个算法,发现这个算法一开始还挺难理解的,也许是我理解能力不是很好吧,花了小半天才看懂,看懂了过后就想分享下,因为觉得这个算法真的挺不错的,以前一直以为字符串搜索算法中KMP算很不错的了,没想到还有更好的,Boyer-Moore算法平均要比KMP快3-5倍。

下面是我对该算法的理解,参考了一些关于该算法的介绍,里面每一张图都画的很认真,希望能讲清楚问题,有什么错误、疑问或不懂的地方麻烦大家一定要提出来,共同学习进步!下面正文开始。

1. 简单介绍

在用于查找子字符串的算法当中,BM(Boyer-Moore)算法是目前被认为最高效的字符串搜索算法,它由Bob Boyer和J Strother Moore设计于1977年。 一般情况下,比KMP算法快3-5倍。该算法常用于文本编辑器中的搜索匹配功能,比如大家所熟知的GNU grep命令使用的就是该算法,这也是GNU grep比BSD grep快的一个重要原因,具体推荐看下我最近的一篇译文“为什么GNU grep如此之快?”作者是GNU grep的编写者Mike Haertel。

2. 主要特征

假设文本串text长度为n,模式串pattern长度为m,BM算法的主要特征为:

- 从右往左进行比较匹配(一般的字符串搜索算法如KMP都是从从左往右进行匹配);

- 算法分为两个阶段:预处理阶段和搜索阶段;

- 预处理阶段时间和空间复杂度都是是O(m+grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)),grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)是字符集大小,一般为256;

- 搜索阶段时间复杂度是O(mn);

- 当模式串是非周期性的,在最坏的情况下算法需要进行3n次字符比较操作;

- 算法在最好的情况下达到O(n / m),比如在文本串bn中搜索模式串am-1b ,只需要n/m次比较。

这些特征先让大家对该算法有个基本的了解,等看懂了算法再来看这些特征又会有些额外的收获。

3.算法基本思想

常规的匹配算法移动模式串的时候是从左到右,而进行比较的时候也是从左到右的,基本框架是:

j = 0;

while(j <= strlen(text) - strlen(pattern)){
for (i = 0; i < strlen(pattern) && pattern[i] == text[i + j]; ++i); if (i == strlen(pattern)) {
Match;
break;
}
else
++j;
}

而BM算法在移动模式串的时候是从左到右,而进行比较的时候是从右到左的,基本框架是:

j = 0;

while(j <= strlen(text) - strlen(pattern)){
for (i = strlen(pattern); i >= 0 && pattern[i] == text[i + j]; --i); if (i < 0)) {
Match;
break;
}
else
j += BM();
}

BM算法的精华就在于BM(text, pattern),也就是BM算法当不匹配的时候一次性可以跳过不止一个字符。即它不需要对被搜索的字符串中的字符进行逐一比较,而会跳过其中某些部分。通常搜索关键字越长,算法速度越快。它的效率来自于这样的事实:对于每一次失败的匹配尝试,算法都能够使用这些信息来排除尽可能多的无法匹配的位置。即它充分利用待搜索字符串的一些特征,加快了搜索的步骤。

BM算法实际上包含两个并行的算法(也就是两个启发策略):坏字符算法(bad-character shift)和好后缀算法(good-suffix shift)。这两种算法的目的就是让模式串每次向右移动尽可能大的距离(即上面的BM()尽可能大)。

下面不直接书面解释这两个算法,为了更加通俗易懂,先用实例说明吧,这是最容易接受的方式。

4. 字符串搜索头脑风暴

大家来头脑风暴下:如何加快字符串搜索?举个很简单的例子,如下图所示,navie表示一般做法,逐个进行比对,从右向左,最后一个字符c与text中的d不匹配,pattern右移一位。但大家看一下这个d有什么特征?pattern中没有d,因此你不管右移1、2、3、4位肯定还是不匹配,何必花这个功夫呢?直接右移5(strlen(pattern))位再进行比对不是更好吗?好,就这样做,右移5位后,text中的b与pattern中的c比较,发现还是不同,这时咋办?b在pattern中有所以不能一下右移5位了,难道直接右移一位吗?No,可以直接将pattern中的b右移到text中b的位置进行比对,但是pattern中有两个b,右移哪个b呢?保险的办法是用最右边的b与text进行比对,为啥?下图说的很清楚了,用最左边的b太激进了,容易漏掉真正的匹配,图中用最右边的b后发现正好所有的都匹配成功了,如果用最左边的不就错过了这个匹配项吗?这个启发式搜索就是BM算法做的。

grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)

图1

But, 如果遇到下面这样的情况,开始pattern中的c和text中的b不匹配,Ok,按上面的规则将pattern右移直至最右边的b与text的b对齐进行比对。再将pattern中的c与text中的c进行比对,匹配继续往左比对,直到位置3处pattern中的a与text中的b不匹配了,按上面讲的启发式规则应该将pattern中最右边的b与text的b对齐,可这时发现啥了?pattern走了回头路,干吗?当然不干,才不要那么傻,针对这种情况,只需要将pattern简单的右移一步即可,坚持不走回头路!

aaarticlea/png;base64,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" alt="" />

图2

好了,这就是所谓的“坏字符算法”,简单吧,通俗易懂吧,上面用红色粗体字标注出来的b就是“坏字符”,即不匹配的字符,坏字符是针对text的。

BM难道就这么简单?就一个启发式规则就搞定了?当然不是了,大家再次头脑风暴一下,有没有其他加快字符串搜索的方法呢?比如下面的例子

aaarticlea/png;base64,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" alt="" />

图3

一开始利用了坏字符算法一下移了4位,不错,接下来遇到了回头路,没办法只能保守移一位,但真的就只能移一位吗?No,因为pattern中前面其他位置也有刚刚匹配成功的后缀ab,那么将pattern前面的ab右移到text刚匹配成功的ab对齐继续往前匹配不是更好吗?这样就可以一次性右移两位了,很好的有一个启发式搜索规则啊。有人可能想:要是前面没已经匹配成功的后缀咋办?是不是就无效了?不完全是,这要看情况了,比如下面这个例子。

aaarticlea/png;base64,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" alt="" />

图4

cbab这个后缀已经成功匹配,然后b没成功,而pattern前面也没发现cbab这样的串,这样就直接保守移一位?No,前面有ab啊,这是cbab后缀的一部分,也可以好好利用,直接将pattern前面的ab右移到text已经匹配成功的ab位置处继续往前匹配,这样一下子就右移了四位,很好。当然,如果前面完全没已经匹配成功的后缀或部分后缀,比如最前面的babac,那就真的不能利用了。

好了,这就是所谓的“好后缀算法”,简单吧,通俗易懂吧,上面用红色字标注出来的ab(前面例子)和cbab(上面例子)就是“好后缀”,好后缀是针对pattern的。

下面,最后再举个例子说明啥是坏字符,啥是好后缀。

主串  :  mahtavaatalomaisema omalomailuun

模式串: maisemaomaloma

坏字符:主串中的“t”为坏字符。

好后缀:模式串中的aloma为“好后缀”。

BM就这么简单?是的,容易理解但并不是每个人都能想到的两个启发式搜索规则就造就了BM这样一个优秀的算法。那么又有个问题?这两个算法怎么运用,一下坏字符的,一下好后缀的,什么时候该用坏字符?什么时候该用好后缀呢?很好的问题,这就要看哪个右移的位数多了,比如上面的例子,一开始如果用好后缀的话只能移一位而用坏字符就能右移三位,此时当然选择坏字符算法了。接下来如果继续用坏字符则只能右移一位而用好后缀就能一下右移四位,这时候你说用啥呢?So,这两个算法是“并行”的,哪个大用哪个。

光用例子说明当然不够,太浅了,而且还不一定能完全覆盖所有情况,不精确。下面就开始真正的理论探讨了。

5. BM算法理论探讨

(1)坏字符算法

当出现一个坏字符时, BM算法向右移动模式串, 让模式串中最靠右的对应字符与坏字符相对,然后继续匹配。坏字符算法有两种情况。

Case1:模式串中有对应的坏字符时,让模式串中最靠右的对应字符与坏字符相对(PS:BM不可能走回头路,因为若是回头路,则移动距离就是负数了,肯定不是最大移动步数了),如下图。

aaarticlea/png;base64,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" alt="" />

Case2:模式串中不存在坏字符,很好,直接右移整个模式串长度这么大步数,如下图。

aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAfIAAAB1CAIAAAA6MfRTAAAKQ0lEQVR4nO2dsbWjPBNAVYJaIHQBaoAS1JAqogSlGxK+kBbseBP+YD70a+1nwNigsbhz7tljszwsxtK1LGRhxr83AACoBlO8BAAA8EHQOgBAVaB1AICqQOsAAFWB1gEAqgKtAwBUBVoHAKgKtA4AUBVoHQCgKtA6AEBVoHUAgKpA6wAAVbGv1j2hLJqtYa3d/LdniNJvLHHG6LruaK177w1BEASxT3jvy2h9128D8BLyjnSvR9M0xpgf4knMNDCAnUDrcBvR+m6B1uF40Drcxuda995ba51zaH1boHU4HrQOt3G2t940DVrfHGgdjgetw218rvUQgjEmhIDWtwVah+NZpfVhGEIIwzCkLV3XxRg3vypa18b8IAxa3xxoHY5nldbbto0xNk2TzC6zcTe/KlrXxjOtO+eccyGENBlWp9ZjjN77GGPaIh9FBYskgdbheFZpXVp1rnX5Yr75VdG6Np5p3VprrRWhe+8fu+1KtC6j/03TJLNLz6NsqX7QOpRgldal19a2bXpqjGEQpiaeaV3qRxqQedxHidbly0SudSl52VL9oHUowSqtxxhzj8tltHdeFa1r41dly8bUQ9es9RDC5XJxzqWnUtSypfpB61CCVVr33jvnrterPH1zYH1E6/qY0Xr+1FqrU+vyxSJ5XEpetkgSaB2OZ63W0wiM9NzfGVgf0bo+nmk993gaZFeode/95XJJT6XnEUIoWCQJtA7Hs3beulw1DSFIM37zVdG6NhZ76865x666Kq2nEZhuuiTA2Dqck1Va7/s+n9qYeu6bQevamJm3Lt/Vfp3dqEfrP9NV0zQRk5kwcFpWaV26aePfm3wTf2cOjIDWtcFSXzsFWofjWTu2HmOUvlv3ZHX2l0Dr2kDrOwVah+NZpfXr9RpjjDGmyTBvgta1gdZ3CrQOx8NSX3Ab0fpugdbheNA63Ea0vlugdTgetA63Ea3vFmgdjqek1gmCIIg9ooDWxeyEqmi2hrV289+eIUq/scQZ42lHvvhXCQAA+CBoHQCgKtA6AEBVoHUAgKpA6wAAVYHWAQCqAq0DAFQFWgcAqAq0DgBQFWgdAKAq0DoAQFWgdQCAqkDrAABVgdYBAKoCrf9H13WlV9ncPZxzmxeeZWHe+ShegQESaH1KBEG8EZgd9IDWp0Sc4L5lco7c9O6DMQzDz88PWgdVoPUpEWgdrb8eaB0UgtanRKB1tP56oHVQCFqfEoHW0frrgdZBIWh9SgRaR+uvB1oHhaD1KRFoHa2/HmgdFPKVWh+GIYTQdd349xZjDCHEGN9NBFpH66/HotbTjwaKv/s70U0/+CheEkh8n9bF6eMkKdF627bvJuLcWk/2CSHIR6ZCrccY5R1PW6SoBYv0q9ZTPmVKe93Wk5NN8/frPtlv4fu0ngxujJHHwzBIz/2tRJxV6/KhKNtDCM4555xOrUvBmqZJZm+axntfsEhJ69baXOUnFNzdh1mqbMULdkK+T+tSUfq+N8ZIt/0ziTir1pumads2PX22jwatizVyrUtpCxYpaZ2Yiepblja+T+tCjNEY8/6Q+v8TcYLKZx6UHUIwxqRRF+lqqR2ECSFcLhfnXHpqjFEyCJNClohxzm1Ztef7I607lCeEPvvRLb14CbYhFeh6vY5/bx/ps59T6957MeOvT7VpXb5MJI9LacsW6W5sXdSW91L9OQYifj3x4qU6LV+mdRkIHoahbds0yP7+9dLxxFq31qan1to0zq5Q6977y+Xy588feSoD6yGEgkWamQlzZ7ri7/5O+H+vDJ/hM0w/X1bbYoxt28qMRj9N2/hMIs6q9dQ9lzEN+RqkVutpBKabLgN4HWPrzFsHPXyZ1ndMxCm13v27yrzMhFHbW/+ZrpqmjqGemTBoHfSA1qdEnFXra0KP1rUFWgeFoPUpEWgdrb8epbQug5DPJoPJl5i7/eWqCR8/ZwCtT4lA62j99SjYW5+Z43un9b7vrbVyRSqVs+/7vu+L10nYA7Q+JQKto/XXQ6fW1+zZdd0Hf/YBqkDrUyLQOlp/Pb5U68MwyI91i9dJ2AO0PiWCIN6IXbUuy9uFEPLlj5Ks5b+So9NibempjMKnSeUyFCNb5JjFWx98FrT+H92/U/2qjPTD7g1hrd38t2eIXStn+sFdvlipaN17L142WX88/7He+Ftv/eNrb4Aq0DqAaqS7nfrUd1pPP8fLH6P1k4PWAVQjCm6mhTZlHaTxQc1oHRJoHUA7XdeJqU12Yf9TWmeaY32gdQDVdNniWbJujzz+lNY/slIeqAKtA6jmbj07a608QOvwDLQOoBrRuvc+v3aaFg/w3ssPi4wxMvgeQpDJOTJ5Md8zn84oAzv5xVioBrQOAFAVaB0AoCrQOgBAVaB1AICqQOsAAFWB1gEAqgKtAwBUBVoHAKgKtA6rKLWYMFFB5OsfwAGgdVjGe7/7fSiIqqN4HT4VpBuWEa0XLwZ8I1Se4yHdsAwtEzZD5Tke0g3L0DJhM1Se4yHdsAwtU2iaxk93sdCGLNyocJVdKs/xkG5YpuKW2ff9+tsDadb69Xp1zqF1GNE6rKHilimLlRcvxvuovT1pxZVHLaS7QoZhCCHIZOEYYwjhzdZea8schqFpGoUq3EAIwVqr8MaktVYezZDu2hCnj39vxhjvvWj9ze/m2lqmnKNEknLamP/4RU5f7gp0t3+MsWka83DboPzg+Z2D7g4+c+T8IMMwzPwYZ/4gM+f1iNzoLv9EV4K2ynMGSHdtJIMbY+TxvFnWoKplyt3aRLjpls3y0ZU2Pt7J0093d8tHKn4duEg3ApWLkL/+1+KR026Ln6kzB5k/rzvkRnfyRr///eyDqKo8J4F014Y07L7vTXbP4jfR0zKHYbDW5ucVYxyG4c6GcpfOtEOeivzxr1qX+38+7jw+0frjkfObjo5L94CeKd78ed2R/2HXdUrer1FT5TkPpLtOPnsBTU/LTN3z+Y35lrtULGp9/Hvr+95737btGq0/Hlm2y3TDruuu1+v6dyp/xfnzyhGPp4M8260IeirPeSDddeK9d86JUN7vs+tpmftpPV1slEEeebpN6+kg8sEwPyfyI1q/2/44fFQQPZXnPJDuqkhDsbmA3p/LrKdl3nVL8413eUheW6n1lKV8kEd2TsMyK7WeX8lY7DjPfzbMnNfM9jTIrgE9lec8kO6qiDG2bStXzGSCx0eG11W1TOdc3v+Vx9bau8H0fMrKS1q/G0uRZMqWlVq/S7u1dv4te1a8+fPKyT8A2radf8WDUVV5TgLphmW0tUy5Jin/ihCHYZClvaXfms91kcLLqt9iRhnylh1ktCS/wilb5OBpFEXMLrNNUv/92ZFF66mE+SzJOxaL9+y8fs1JetHib5DmynMGSDcsQ8uEzVB5jod0wzK0TNgMled4SDcsQ8uEzVB5jod0wzK0TNgMled4SDcsQ8uEzVB5jod0wzJptgZBbAi0fjCkG5aRadEEsS281nuP1ApaBwCoCrQOAFAVaB0AoCrQOgBAVfwP016234uo2VYAAAAASUVORK5CYII=" alt="" />

(2)好后缀算法

如果程序匹配了一个好后缀, 并且在模式中还有另外一个相同的后缀或后缀的部分, 那把下一个后缀或部分移动到当前后缀位置。假如说,pattern的后u个字符和text都已经匹配了,但是接下来的一个字符不匹配,我需要移动才能匹配。如果说后u个字符在pattern其他位置也出现过或部分出现,我们将pattern右移到前面的u个字符或部分和最后的u个字符或部分相同,如果说后u个字符在pattern其他位置完全没有出现,很好,直接右移整个pattern。这样,好后缀算法有三种情况,如下图所示:

Case1:模式串中有子串和好后缀完全匹配,则将最靠右的那个子串移动到好后缀的位置继续进行匹配。

aaarticlea/png;base64,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" alt="" />

Case2:如果不存在和好后缀完全匹配的子串,则在好后缀中找到具有如下特征的最长子串,使得P[m-s…m]=P[0…s]。

aaarticlea/png;base64,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" alt="" />

Case3:如果完全不存在和好后缀匹配的子串,则右移整个模式串。

(3)移动规则

BM算法的移动规则是:

将3中算法基本框架中的j += BM(),换成j += MAX(shift(好后缀),shift(坏字符)),即

BM算法是每次向右移动模式串的距离是,按照好后缀算法和坏字符算法计算得到的最大值。

shift(好后缀)和shift(坏字符)通过模式串的预处理数组的简单计算得到。坏字符算法的预处理数组是bmBc[],好后缀算法的预处理数组是bmGs[]。

6. BM算法具体执行

BM算法子串比较失配时,按坏字符算法计算pattern需要右移的距离,要借助bmBc数组,而按好后缀算法计算pattern右移的距离则要借助bmGs数组。下面讲下怎么计算bmBc[]和bmGs[]这两个预处理数组。

(1)计算坏字符数组bmBc[]

这个计算应该很容易,似乎只需要bmBc[i] = m - 1 - i就行了,但这样是不对的,因为i位置处的字符可能在pattern中多处出现(如下图所示),而我们需要的是最右边的位置,这样就需要每次循环判断了,非常麻烦,性能差。这里有个小技巧,就是使用字符作为下标而不是位置数字作为下标。这样只需要遍历一遍即可,这貌似是空间换时间的做法,但如果是纯8位字符也只需要256个空间大小,而且对于大模式,可能本身长度就超过了256,所以这样做是值得的(这也是为什么数据越大,BM算法越高效的原因之一)。

aaarticlea/png;base64,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" alt="" />

如前所述,bmBc[]的计算分两种情况,与前一一对应。

Case1:字符在模式串中有出现,bmBc['v']表示字符v在模式串中最后一次出现的位置,距离模式串串尾的长度,如上图所示。

Case2:字符在模式串中没有出现,如模式串中没有字符v,则BmBc['v'] = strlen(pattern)。

写成代码也非常简单:

void PreBmBc(char *pattern, int m, int bmBc[])
{
int i; for(i = 0; i < 256; i++)
{
bmBc[i] = m;
} for(i = 0; i < m - 1; i++)
{
bmBc[pattern[i]] = m - 1 - i;
}
}

计算pattern需要右移的距离,要借助bmBc数组,那么bmBc的值是不是就是pattern实际要右移的距离呢?No,想想也不是,比如前面举例说到利用bmBc算法还可能走回头路,也就是右移的距离是负数,而bmBc的值绝对不可能是负数,所以两者不相等。那么pattern实际右移的距离怎么算呢?这个就要看text中坏字符的位置了,前面说过坏字符算法是针对text的,还是看图吧,一目了然。图中v是text中的坏字符(对应位置i+j),在pattern中对应不匹配的位置为i,那么pattern实际要右移的距离就是:bmBc['v'] - m + 1 + i。

aaarticlea/png;base64,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" alt="" />

(2)计算好后缀数组bmGs[]

这里bmGs[]的下标是数字而不是字符了,表示字符在pattern中位置。

如前所述,bmGs数组的计算分三种情况,与前一一对应。假设图中好后缀长度用数组suff[]表示。

Case1:对应好后缀算法case1,如下图,j是好后缀之前的那个位置。

aaarticlea/png;base64,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" alt="" />

Case2:对应好后缀算法case2:如下图所示:

aaarticlea/png;base64,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" alt="" />

Case3:对应与好后缀算法case3,bmGs[i] = strlen(pattern)= m

aaarticlea/png;base64,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" alt="" />

这样就清晰了,代码编写也比较简单:

void PreBmGs(char *pattern, int m, int bmGs[])
{
int i, j;
int suff[SIZE]; // 计算后缀数组
suffix(pattern, m, suff); // 先全部赋值为m,包含Case3
for(i = 0; i < m; i++)
{
bmGs[i] = m;
} // Case2
j = 0;
for(i = m - 1; i >= 0; i--)
{
if(suff[i] == i + 1)
{
for(; j < m - 1 - i; j++)
{
if(bmGs[j] == m)
bmGs[j] = m - 1 - i;
}
}
} // Case1
for(i = 0; i <= m - 2; i++)
{
bmGs[m - 1 - suff[i]] = m - 1 - i;
}
}

So easy? 结束了吗?还差一步呢,这里的suff[]咋求呢?

在计算bmGc数组时,为提高效率,先计算辅助数组suff[]表示好后缀的长度。

suff数组的定义:m是pattern的长度

a. suffix[m-1] = m;
b. suffix[i] = k  
    for [ pattern[i-k+1] ....,pattern[i]] == [pattern[m-1-k+1],pattern[m-1]]

看上去有些晦涩难懂,实际上suff[i]就是求pattern中以i位置字符为后缀和以最后一个字符为后缀的公共后缀串的长度。不知道这样说清楚了没有,还是举个例子吧:

i     : 0 1 2 3 4 5 6 7 
pattern: b c  a b a b a b

当i=7时,按定义suff[7] = strlen(pattern) = 8

当i=6时,以pattern[6]为后缀的后缀串为bcababa,以最后一个字符b为后缀的后缀串为bcababab,两者没有公共后缀串,所以suff[6] = 0

当i=5时,以pattern[5]为后缀的后缀串为bcabab,以最后一个字符b为后缀的后缀串为bcababab,两者的公共后缀串为abab,所以suff[5] = 4

以此类推……

当i=0时,以pattern[0]为后缀的后缀串为b,以最后一个字符b为后缀的后缀串为bcababab,两者的公共后缀串为b,所以suff[0] = 1

这样看来代码也很好写:

void suffix(char *pattern, int m, int suff[])
{
int i, j;
int k; suff[m - 1] = m; for(i = m - 2; i >= 0; i--)
{
j = i;
while(j >= 0 && pattern[j] == pattern[m - 1 - i + j]) j--; suff[i] = i - j;
}
}

这样可能就万事大吉了,可是总有人对这个算法不满意,感觉太暴力了,于是有聪明人想出一种方法,对上述常规方法进行改进。基本的扫描都是从右向左,改进的地方就是利用了已经计算得到的suff[]值,计算现在正在计算的suff[]值。具体怎么利用,看下图:

i是当前正准备计算suff[]值的那个位置。

f是上一个成功进行匹配的起始位置(不是每个位置都能进行成功匹配的,  实际上能够进行成功匹配的位置并不多)。

g是上一次进行成功匹配的失配位置。

如果i在g和f之间,那么一定有P[i]=P[m-1-f+i];并且如果suff[m-1-f+i] < i-g, 则suff[i] = suff[m-1-f+i],这不就利用了前面的suff了吗。

aaarticlea/png;base64,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" alt="" />

PS:这里有些人可能觉得应该是suff[m-1-f+i] <= i - g,因为若suff[m-1-f+i] = i - g,还是没超过suff[f]的范围,依然可以利用前面的suff[],但这是错误的,比如一个极端的例子:

i      :0 1 2 3 4 5 6 7 8 9
pattern:a  a a a a b a a a  a

suff[4] = 4,这里f=4,g=0,当i=3是,这时suff[m-1=f+i]=suff[8]=3,而suff[3]=4,两者不相等,因为上一次的失配位置g可能会在这次得到匹配。

好了,这样解释过后,代码也比较简单:

void suffix(char *pattern, int m, int suff[]) {
int f, g, i; suff[m - 1] = m;
g = m - 1;
for (i = m - 2; i >= 0; --i) {
if (i > g && suff[i + m - 1 - f] < i - g)
suff[i] = suff[i + m - 1 - f];
else {
if (i < g)
g = i;
f = i;
while (g >= 0 && pattern[g] == pattern[g + m - 1 - f])
--g;
suff[i] = f - g;
}
}
}

结束了?OK,可以说重要的算法都完成了,希望大家能够看懂,为了验证大家到底有没有完全看明白,下面出个简单的例子,大家算一下bmBc[]、suff[]和bmGs[]吧。

举例如下:

aaarticlea/png;base64,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" alt="" />

PS:这里也许有人会问:bmBc['b']怎么等于2,它不是最后出现在pattern最后一个位置吗?按定义应该是0啊。请大家仔细看下bmBc的算法:

for(i = 0; i < m - 1; i++)
{
bmBc[pattern[i]] = m - 1 - i;
}

这里是i < m - 1不是i < m,也就是最后一个字符如果没有在前面出现过,那么它的bmBc值为m。为什么最后一位不计算在bmBc中呢?很容易想啊,如果记在内该字符的bmBc就是0,按前所述,pattern需要右移的距离bmBc['v']-m+1+i=-m+1+i <= 0,也就是原地不动或走回头路,当然不干了,前面这种情况已经说的很清楚了,所以这里是m-1。

好了,所有的终于都讲完了,下面整合一下这些算法吧。

#include <stdio.h>
#include <string.h> #define MAX_CHAR 256
#define SIZE 256
#define MAX(x, y) (x) > (y) ? (x) : (y) void BoyerMoore(char *pattern, int m, char *text, int n); int main()
{
char text[256], pattern[256]; while(1)
{
scanf("%s%s", text, pattern);
if(text == 0 || pattern == 0) break; BoyerMoore(pattern, strlen(pattern), text, strlen(text));
printf("\n");
} return 0;
} void print(int *array, int n, char *arrayName)
{
int i;
printf("%s: ", arrayName);
for(i = 0; i < n; i++)
{
printf("%d ", array[i]);
}
printf("\n");
} void PreBmBc(char *pattern, int m, int bmBc[])
{
int i; for(i = 0; i < MAX_CHAR; i++)
{
bmBc[i] = m;
} for(i = 0; i < m - 1; i++)
{
bmBc[pattern[i]] = m - 1 - i;
} /* printf("bmBc[]: ");
for(i = 0; i < m; i++)
{
printf("%d ", bmBc[pattern[i]]);
}
printf("\n"); */
} void suffix_old(char *pattern, int m, int suff[])
{
int i, j; suff[m - 1] = m; for(i = m - 2; i >= 0; i--)
{
j = i;
while(j >= 0 && pattern[j] == pattern[m - 1 - i + j]) j--; suff[i] = i - j;
}
} void suffix(char *pattern, int m, int suff[]) {
int f, g, i; suff[m - 1] = m;
g = m - 1;
for (i = m - 2; i >= 0; --i) {
if (i > g && suff[i + m - 1 - f] < i - g)
suff[i] = suff[i + m - 1 - f];
else {
if (i < g)
g = i;
f = i;
while (g >= 0 && pattern[g] == pattern[g + m - 1 - f])
--g;
suff[i] = f - g;
}
} // print(suff, m, "suff[]");
} void PreBmGs(char *pattern, int m, int bmGs[])
{
int i, j;
int suff[SIZE]; // 计算后缀数组
suffix(pattern, m, suff); // 先全部赋值为m,包含Case3
for(i = 0; i < m; i++)
{
bmGs[i] = m;
} // Case2
j = 0;
for(i = m - 1; i >= 0; i--)
{
if(suff[i] == i + 1)
{
for(; j < m - 1 - i; j++)
{
if(bmGs[j] == m)
bmGs[j] = m - 1 - i;
}
}
} // Case1
for(i = 0; i <= m - 2; i++)
{
bmGs[m - 1 - suff[i]] = m - 1 - i;
} // print(bmGs, m, "bmGs[]");
} void BoyerMoore(char *pattern, int m, char *text, int n)
{
int i, j, bmBc[MAX_CHAR], bmGs[SIZE]; // Preprocessing
PreBmBc(pattern, m, bmBc);
PreBmGs(pattern, m, bmGs); // Searching
j = 0;
while(j <= n - m)
{
for(i = m - 1; i >= 0 && pattern[i] == text[i + j]; i--);
if(i < 0)
{
printf("Find it, the position is %d\n", j);
j += bmGs[0];
return;
}
else
{
j += MAX(bmBc[text[i + j]] - m + 1 + i, bmGs[i]);
}
} printf("No find.\n");
}

运行效果如下:

aaarticlea/png;base64,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" alt="" />

参考资料

1. Boyer-Moore algorithm

2. wiki: Boyer–Moore string search algorithm

3. Boyer-Moore算法学习