- BM(Boyer-Moore) 算法,它是一种非常高效的字符串匹配算法
- 坏字符规则(bad character rule)
- BM算法匹配顺序比较特别,它是按照模式串下标从大到小的顺序,倒着匹配
- 从模式串的末尾往前倒着匹配,当发现到某个字符没法匹配的时候,就可以把这个不可以匹配的字符叫做
坏字符(主串中的字符) - 移动规则
- 规则总结
- 坏字符规则的缺点
- si - xi 可能会计算出负数。
- 例如
- 主串:aaaaaaaaaaaaaaaa
- 模式串: baaa
- 不但不会向后滑动模式串,还有可能倒退
- 坏字符规则表的创建
- 可以通过散列表的方式,将模式串中的每个字符及其下标都存到散列表中
- 坏字符表,怎么处理多个相同字母的hash值
- 相同的字母取最后一个
- 为什么取最后一个?
- 最小限度的移动,为了不错误完全匹配的机会
- 坏字符规则时间复杂度
- O(n / m)
- 好后缀规则(good suffix shift)

- 移动规则
一. 把已经匹配的bc叫做好后缀,记作{u}.然后拿它在模式串中查找,如果找到另一个跟{u}相匹配的子串{u*},那么就将模式串滑动到子串{u*}与主串中{u}对齐的位置二. 当模式串不存在等于{u}的子串时,直接将模式串滑动到主串{u}后面?,
- 实现
- 如果表示模式串不同的后缀子串?

- suffix 数组下标k,表示后缀字符串的长度
- 下标对应的数组值存储的是。好后缀{u}相匹配子串{u*}的起始下标值
- 例子
- cabcab 模式串,拆分前缀子串和后缀子串,求公共子串?
- 前缀
- c, ca, cab, cabc, cabca
- 后缀
- b, ba, bac, cbacb, bacba
- 前后缀访问顺序
- 前缀:从右往左遍历
- 后缀:从左往右遍历
- 公共子串
- 因为 cab == bac. 所以,取前缀中的 cab
- 然后按好后缀{u}的模式拆分子串
- b = 2
- ab = 1
- cab = 0
- 前缀
- cabcab 模式串,拆分前缀子串和后缀子串,求公共子串?
- 为什么要求公共子串?
- 因为好后缀是主串与模式串的最长匹配子串,所以好后缀也是模式串的后缀子串
- 而公共子子串,则是好后缀的最长的可匹配子串
- 为什么要把公共子串拆分为N个小的子串?
- 为了划分出N个可让好后缀匹配的子串(把整个好后缀拆分开,一一与公共子串N个子串匹配)
- 模式串的前缀子串:模式串与主串匹配时,坏字符位置以前的模式串长度
- 例如
igfqoofimcab cabicab- 好后缀:cab
- 坏字符: m
- 模式串的前缀子串: cab
- 好后缀的后缀子串:b, ab, cab
- 与好后缀的后缀子串能跟模式串前缀子串匹配的后缀子串:b, ab, cab
- 不仅仅要在模式串中,查找跟好后缀匹配的另一个子串,还要在好后缀子串中,查找最长的能跟模式串前缀子串匹配的后缀子串(概念上文已述)
- 如果表示模式串不同的后缀子串?
- BM算法时间复杂度
- 预处理时间:O(m ^ 2)












