KMP就是字符串匹配算法,最樸素的字符串匹配算法,就是逐位匹配,不匹配就右移一位,這種方法效率太低。爲了節省時間,利用已經匹配過的部分字符串的信息來爲後續的匹配提供條件,減少匹配次數。
KMP算法的關鍵就是獲取next值,next[ j ] 是通過模式串得來的,關於next[ j ] 的算法也有普通和改進的,
普通的獲取next[ j ]的算法思想是:
1)、next[j]=-1 j=0
2)、next[j]=max k:0<k<j, P[0...k-1]=P[j-k,j-1]
3)、next[j]=0 其他
利用得到的next[]函數,進行KMP匹配,其思想就是:
在匹配過程中,若發生不匹配的情況,如果next[j]>=0,則目標串的指針i不變,將模式串的指針j移動到next[j]的位置繼續進行匹配;若next[j]=-1,則將i右移1位,並將j置0,繼續進行比較。
上面就是KMP算法的兩個關鍵點。然而關於求next[ ]值,又有多種不同的方法,產生不同方法的原因是,改進樸素的方法,使匹配的結果更準確,效率更高。常用的求next[]的方法有遞推式和直接求解式。
遞推的思想:
根據定義next[0]=-1,假設next[j]=k, 即P[0...k-1]==P[j-k,j-1]
1)若P[j]==P[k],則有P[0..k]==P[j-k,j],很顯然,next[j+1]=next[j]+1=k+1;
2)若P[j]!=P[k],則可以把其看做模式匹配的問題,即匹配失敗的時候,k值如何移動,顯然k=next[k]。
代碼:
void
getNext(
char
*p,
int
*next)
{
int
j,k;
next[0]=-1;
j=0;
k=-1;
while
(j<
strlen
(p)-1)
{
if
(k==-1||p[j]==p[k])
//匹配的情況下,p[j]==p[k]
{
j++;
k++;
next[j]=k;
}
else
//p[j]!=p[k]
k=next[k];
}
}