字符串匹配算法

字符串匹配算法,即在一个字符串中查找另个字符串的位置。如果在字符串A中查找字符串B是否存在,那么字符串A称为主串,字符串B称为模式串。主串长度为m,模式串长度为n。

字符串匹配算法_第1张图片
字符串匹配

BF (Brute Force) 暴力匹配算法

充主串A的起始位0开始,检查长度n的子串,是否和模式串相等。如果不相等,将主串的指针往后挪一位,从主串的1,2,3 ... m-n位开始,依次检查长度为n的子串,是否和模式串匹配。


字符串匹配算法_第2张图片
BF算法

时间复杂度为 O(m*n),但是实际的效率比理论值效率高一些。

RK(Rabin-Karp)算法

和BF算法思想一致,只是在比较A的子串与模式串是否匹配时,使用Hash算法比较hash后的数值,而不是一一比较字符。


字符串匹配算法_第3张图片
RK算法

其中的Hash算法比较讲究,好的Hash算法可以大大提高效率,而查的Hash算法,可能使得算法效率还比不上BF。
如果字符串只有小写字符,可将字符串作为26进制的数来看待。同时缓存26n,26(n-1) 等预处理的值,可以提高计算速度。

BM(Boyer-Moore)算法

非常高效的算法,据说是KMP算法的3-4倍。算法思路上与BF一致,只是每次往后挪的位数多一些。而且在比较子串与模式串时,是从最后一个字符开始,往前比较。

  • 坏字符规则(bad character rule)
  • 好后缀规则(good suffix rule)

坏字符规则

从后往前,依次比较主串和模式串的字符,出现不相等的字符时,主串中的那个就是“坏字符”。
如果模式串中有坏字符,将模式串往后移动让两个字符对齐。如果模式串中没有坏字符,直接将模式串移到坏字符后面。


字符串匹配算法_第4张图片
BM算法

好后缀规则

主串和模式串从后往前,相同的部分称为“好后缀”。

  • 模式串中有好后缀,可以后移模式串,让二者对齐。


    字符串匹配算法_第5张图片
    好后缀规则1
  • 好后缀的后面的子串和模式串前缀子串相同,移动模式串到相应的位置。


    字符串匹配算法_第6张图片
    好后缀规则2
  • 其他情况,将模式串挪到好后缀后面。

预处理

要想高效实用这两个规则,需要对模式串进行预处理。

坏字符预处理

将模式串的字符位置放到哈希表,在以便快速查找坏字符。
hash[key] = value;

  • key - 模式串的字符
  • value - 字符在模式串中的位置。
    相同的字符,取最后一个位置。

好后缀预处理

  1. 处理模式串中后缀子串,检查在模式串中其他位置是否有形同的的子串,使用 int[] A 数组来存储。
    A[i] = j;
    表示从后往前 i+1 长度的字符串,在模式串中存在,位置是 j。

  2. 处理模式串的后缀子串,是否与模式串的前缀子串匹配。同样适用 bool[] B 数组来存储。
    B[i] = true/false;
    表示从后往前 i+1 长度的字符串,true表示和前缀子串匹配,false表示不匹配。

代码实现思路如下图,j从 0 -> n-1 遍历,对于每个j,相应的k指向末尾,同时往前移动,如果指向的字符不同,马上停止。得到值存入A。如果j指针能走到0,那B中设置为true。


字符串匹配算法_第7张图片
好后缀预处理算法

你可能感兴趣的:(字符串匹配算法)