KMP算法重溫

        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];
    }
}


發佈了29 篇原創文章 · 獲贊 1 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章