引言:
KMP的时间复杂度是O(n+m)的
但实际上如果无法匹配成功,这个复杂度一般都是能跑满的
linux下常用的grep就用到了字符串匹配算法,但是使用了更快的BM算法
它的理论时间复杂度也是O(n+m)的,但无论能不能匹配成功,一般它都是跑不满的
也就是它实际对比的字符数量一般都是比(n+m)少很多的,所以用起来平均速度能比KMP快几倍
而最坏时间复杂度也是有保障的
原理:
考虑O(nm)的暴力对比进行字符串匹配,我们总是希望某次失配后能根据已有信息进行尽可能多的跳跃
KMP有自己的next数组来进行跳跃
BM呢?最朴素的,我们有坏字符规则
问题:我们要在长度为n的串s中找到长度为m的串t(下标均从0开始)
坏字符规则:
我们首先预处理出所有字符在t中最后一次出现的位置last-occurence
定义last[i]为字符i最后一次在t中出现的位置,可以O(m)得到last数组
我们从前往后枚举s的下标,确定某个位置后,我们从后往前枚举串t的字符,即
for i in [(m - 1) -> n]:
for j in [(m - 1) -> 0]:
...
这样进行匹配,当j匹配到某个位置失配,那么可以直接向后移动last[]
来源:https://www.cnblogs.com/ytytzzz/p/11250277.html