BF算法
1、BF算法(Brute Force):暴力匹配算法,最常用的字符串算法
2、字符串匹配算法中最常用的两个定义:主串与模式串,主串指的是被查找的串,模式串为要查找的串。例:A串中查找B串,则A为主串,B为模式串。
3、BF算法原理:从主串的起始位置分别为0,1,2…n-m检查长度为m(模式串的长度)的n-m+1个子串(n为主串长度),是否有与模式串匹配的字符串。简单的来说,即从头开始,将模式串与主串匹配。
注:若检查的位置到n-m+1,则主串剩余长度小于m,比模式串的长度小,无需匹配。
4、时间复杂度:O(n*m)
RK算法
1、RK算法(Rabin-Karp),在BF算法上进行改良,引入哈希算法,降低了时间复杂度,提高了性能。
2、将主串中的n-m+1个子串分别求哈希值,然后逐个与模式串的哈希值进行比较,若不相同,则说明不匹配;若相同,则还需比较两个字符串,防止哈希冲突。
3、时间复杂度:O(n)
BM算法
1、BM算法与BF、RK的区别:BF、RK匹配模式串时,移动的位数都是一位一位的向后移动,BM算法则借助两个规则(坏字符和好后缀),能够跳过一些肯定不会匹配的情况,将模式串一次性向后多滑动几位。
2、特点:从后往前匹配模式串(BF、RK都是从前往后匹配模式串)
3、坏字符规则:
(1)从模式串的末尾从后往前与主串匹配,当遇到与主串不匹配的字符时,则该字符在主串中即为坏字符。
(2)若坏字符在模式串中不存在,则直接将模式串移动到坏字符后一位的位置上,再开始匹配。
(3)若坏字符在模式串中存在,则将模式串移动到将两个字符对齐的位置,再开始匹配。若坏字符在模式串中多次出现,则选择最靠后的。
(4)总结:坏字符对应模式串的位置下标为Si,坏字符在模式串中的位置下标为Xi(Xi不存在即为-1),则模式串移动位数为Si-Xi。当Si-Xi为负数时,则需要用好后缀规则。
4、好后缀规则:
(1)从模式串的末尾从后往前与主串匹配,模式串与主串匹配的字符串为好后缀{u}。
(2){u}在模式串中不存在时(即除了{u}还有其他的{u}),则直接将模式串移动到{u}后。
(3){u}在模式串中二次存在时,二次存在的{u}记为{u*},将模式串移动到{u}与{u*}对齐的位置。
(4)当{u}没有在模式串二次存在时,为避免二次滑动,若有{u}的后缀子串与模式串的前缀子串匹配,则找到一个最长的字符串{v},将{v}与{u}的后缀子串对齐。
注:假设有字符串abacd
该字符串的前缀子串分别为:a,ab,aba,abac
该字符串的后缀子串分别为:d,cd,acd,bacd
5、两种规则取舍:分别计算坏字符规则和好后缀规则滑动的位数,取最大的进行滑动
6、好后缀规则可以独立于坏字符规则使用,且坏字符实现占用的内存多。
7、主要应用于文本编辑器的全量替换
KMP算法
1、KMP算法与BM算法类似,当遇到坏字符后,之前已匹配的字符串为好前缀
2、在好前缀的后缀子串中查找最长的可与好前缀的前缀子串匹配的字符串a,a在好前缀的所有后缀子串中为最长可匹配后缀子串,a在好前缀的所有前缀子串中为最长可匹配前缀子串。
3、假设a的长度为k,则模式串往后滑动j-k位,j为坏字符在模式串中的位置。
4、时间复杂度:O(m+n)
图源:王争——数据结构与算法之美