模式匹配中Brute-Force与KMP算法关键提取

模式匹配是串结构的一种操作方法,用于串的匹配。待匹配串称为主串(也叫目标串),执行串称为子串(也叫模式串)。模式匹配即查找主串中是否包含子串。

模式匹配有两大经典算法 Brute-Force与KMP

Brute-Force

  简单总结就是粗暴匹配,即子串从0开始与主串依次匹配,若匹配失败,则子串仍从0开始,主串起始位置+1。

缺点就是:容易重复计算 比如abbbbc  abbbd ,那么就衍生出了新的改进算法KMP。

KMP

  具体算法内容自行查阅,关键点:索引抽象,索引对应,重叠抽象

(索引抽象与对应):

主串  S[0] S[1]...S[i-1] S[i] S[i+1]..

子串  T[0] T[1]...T[j-1] T[j] T[j+1]..

假设当S[i] T[j]时 匹配失败,那么前j个必定匹配对应,

(1)当子串前j个中没有形似于 t[0] t[1] t[2]..t[k-1] = t[j-k]..t[j-3] t[j-2] t[j-1]时与Brute-Force相同,

(2)但是当存在这种形式, 举例 abcdabc 前三个后三个相等,那么就可以省略匹配过程 直接从t[k]开始与S[i]匹配,原理就是简单的等式相等传递。

(重叠抽象):

那么根据(2)则把重叠部分抽象出另一个函数next[j],即每个字符的最大真子串 上例中next[j]等于k。通俗解释就是不包括[j]的前j个字符所包含的最大索引数。 有了这个参数则可直接根据上述抽象的结论编程。

next函数的计算(难点):

next函数是根据情况分段的,当j=0时那么next[j]不存在记为-1,当索引字符[x]没重叠真子串时,next[x]为0.

当存在最大真子串时,为k. k的求法巧妙的运用了前后关系,类似于数学归纳法,假设next[j]=k,求出next[j+1]的表达式。

(1)第一种情况 t[k]=s[j]那么正好next[j+1]=next[j]+1。

(2)第二种情况 t[k]!=s[j] t串向右滑操作,直到出现最大真子串 

              t[0-j]      121 1 121 2                121 1 121 2

      t[0-k]            121 1 t右滑                1 21 1  最大真子串就等于2  可将右滑前后的t看作是模式匹配抽象出来即next[k]+1

对于+1的解释:求next[j+1] 必须满足tk=tj 或t'k(右滑位置)=tj,next[j]或者next[k]是不算进[j][k]位置的,所以要加1。

最后就是结束标志:根据串长度判断,一方超出即停止。

你可能感兴趣的:(模式匹配中Brute-Force与KMP算法关键提取)