模式匹配中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。
最后就是结束标志:根据串长度判断,一方超出即停止。