KMP算法
KMP算法
概念
KMP算法是用来解决字符串匹配问题的,与 哈希与哈希表 的第一个例题类似。在这里我们规定:等待匹配的串为主串(母串),用来匹配的串为模式串。
算法实现
KMP算法本质上是通过双指针实现的。我们用两个指针\(i\)和\(j\)表示\(A[i-j+1\cdots i]\)与\(B[1\cdots j]\)完全相匹配。这表明\(i\)在不断增加,\(j\)随\(i\)增加而改变。当处理完\(A[i]\)和\(B[j]\)后,现在需要检验\(A[i+1]\)和\(B[j+1]\)的关系。有两种情况:
-
当\(A[i+1]=B[j+1]\)时,匹配成功,\(i\)和\(j\)各加\(1\)。
-
当\(A[i+1] \neq B[j+1]\)时,KMP的策略是调整\(j\)的值(减小到合适位置),使\(A[i-j+1\cdots i]\)与\(B[1\cdots j]\)依然保持匹配。再尝试匹配\(A[i+1]\)与\(B[j+1]\)。
样例
我们令主串$A = $ "abababaababacb",$B = $ "ababacb"。
当\(i=j=5\)时:
\(i=\) 1 2 3 4 5 6 7 8 9 \(\cdots\)
\(A=\) a b a b a b a a b \(\cdots\)
\(B=\) a b a b a c b
\(j=\) 1 2 3 4 5 6 7
此时\(A[6]\ne B[6]\)。这表明,\(j\ne 5\),我们将\(j\)改为比\(j\)小的\(j'\)。这时,我们发现必须使得\(B[1\cdots j']\)与\(B[m-j'+1\cdots m]\)相同才能保证新的\(j'\)仍然匹配。
现在还剩下一个问题,如何预处理出每一个\(j\)对应的\(j'\)?
令\(P[j]=j'\)。当当前字符串在添加一个字符后仍然满足\(j'\)的条件,也就是满足\(B[j]=B[m-j+1]\)。那么\(P[j]=P[j-1]+1\)。
但如果不满足,我们再考虑\(P[j]=P[P[j]]+1\),以此类推。这样的算法相当于在\(B\)串内部运行一遍\(KMP\),进行自我匹配。

浙公网安备 33010602011771号