kmp演算法(下)——next數組

來源:互聯網
上載者:User

接上一篇。

 

4、如何計算next數組

       對於給定的字串p,其next數組的含義是:對於k=next[j],p的首碼p[0…k-1]和p的尾碼p[j-k…j-1]匹配,k要儘可能的大,且k<j.我們可以根據上述含義寫出next的brute
force計算代碼。複雜度應該是O(n2)。

 

換個思路,現在next[0]=-1,next[1]=0.

假設k=next[j],則p[0…k-1]=p[j-k…j-1],那麼求next[j+1]有兩種情況:

1)如果p[k]=p[j],則p[0…k]=p[j-k…j],所以next[j+1]=k+1=next[j]+1;

2)如果p[k]!=p[j],這是可以看做另外一個字串匹配的問題,主串和模式串都是p,當匹配失敗時,k應該如何移動呢?顯然是k=next[k]。請仔細琢磨這段話。【參考《資料結構-嚴蔚敏》p82-83】

仿照kmp演算法,可以得到next數組的求法:


voidgetNext(const char *p,int *next){    int i,j;    next[0]=-1;    i=0;    j=-1;    while(i<(signed)strlen(p)-1)    {        if(j==-1||p[i]==p[j])    //匹配的情況下,p[j]==p[k]        {            i++;            j++;            next[i]=j;        }        else                   //p[j]!=p[k]            j=next[j];    }}

 

       next數組是kmp演算法的核心,只有真正理解next數組,才能熟練掌握kmp演算法。

 

       複雜度分析:getNext()函數的複雜度是O(m),通常情況下模式串長度m<<主串長度n,因此增加的時間是值得的。由於使用了輔助數組,因此空間複雜度是O(m)。

 

       雖然樸素字串匹配演算法的複雜度是O(n*m),但是在一般情況下實際的執行時間接近O(n+m)。KMP演算法僅當模式串與主串之間存在許多“部分匹配”的情況下(這時才會有大量的回退)才顯得比樸素匹配演算法快得多。KMP演算法的最大優點是不需要回溯指標,對主串僅需要從頭至尾掃描一遍,對於外設輸入龐大的檔案很有效,可以邊讀入遍匹配,無需回頭重讀。



 5、最佳化

其實上面的getNext()還可以最佳化:

voidgetNext(const char *p,int *next)

{

    int i,j;

    next[0]=-1;

    i=0;

    j=-1;

    while(i<(signed)strlen(p)-1)

    {

        if(j==-1||p[i]==p[j])    //匹配的情況下,p[j]==p[k]

        {

            i++;

            j++;

            if(p[i]!=p[j])      next[i]=j;

            else                 next[i]=next[j];///p[i]=p[j]時最佳化

        }

        else                   //p[j]!=p[k]

            j=next[j];

    }

}

這時匹配演算法不變。

       後記:kmp演算法是D.E.Knuth與J.H.Morris與V.R.Pratt同時發現的字串匹配的改良演算法。也是我單個看的最久的演算法。

在網上看很多blog,包括比較有名的matrix67,July等,但是我都沒看太明白。尤其是July的,一大堆,前面的樸素演算法都弄了一堆圖,非常詳細,這點很好。可是後面求next數組時,一會弄個下標從0開始的,一會弄個下標從1開始的,讓新手無所適從。本來就是不懂才看,結果看完更鬱悶了。最後還是看了嚴蔚敏老師的《資料結構》上的,才似乎懂了些。那本書上是下標從1開始的,我感覺講的比網上的blog要詳細的多,易懂的多。這本書之前大二時學習時沒看太細,雖然考試分數挺高,但是顯然書上好多內容都沒有掌握。現在還在看。這裡附上這本書的pdf串連,可以直接下載。


原創文章,轉載請註明出處:http://blog.csdn.net/fastsort/article/details/9971953

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.