解析KMP演算法

來源:互聯網
上載者:User

       

       字串匹配的演算法當屬KMP最為著名了,人人皆知,但是KMP演算法是如何做到高效率字串匹配的呢?

    我們首先來看看一般的暴力的字串匹配演算法,對於串s和模式串pattern,依次枚舉s中的每一個字元作為起點與pattern嘗試進行匹配,直到遇到不匹配的字元的時候,取下一個s中的字元作為起點與模式串pattern重新進行匹配。我們知道這樣的時間複雜度是O(n*m)的,顯然效率很不好。

    從上面暴力匹配的過程我們可以知道,當暴力進行匹配的時候,遇到不匹配的字元,不一定要從s的下一個字元重新與模式串進行匹配,那麼我們如何做到這一點呢?這就要用到KMP中神奇的next數組了。

    next數組記錄的是模式串的特徵,從而當匹配不成功的時候,我們不一定完全對s的下一個字元與模式串從頭開始匹配。於是next[i]表示當i與s中的某個串匹配不成功的時候,我們應該用第next[i]的字元與s中的當前位進行匹配。也就是說模式串pattern的子串[pattern[0], pattern[next[k]-1]]與子串[pattern[k-next[k]],
pattern[k-1]]完全相同。

    我們為什麼能將next數組用在與s的匹配過程中呢?因為當s[i]與patter[k]不匹配的時候,說明pattern的子串[pattern[0], pattern[k-1]]已經與s的子串[s[i-k], s[i-1]]完全符合了,而這個時候藉助next數組,我們知道如果pattern有一個首碼與s[0, i-1]的某一個尾碼完全相同,我們就應該將首碼的最後一個字元的後面一個字元同s[i]進行嘗試匹配。這樣子大大的減少了沒有作用的盲目匹配嘗試。

    我們可以預見KMP演算法的均攤複雜度是O(n+m),為什麼呢?因為你的s串是不會回退的,因此最多訪問了n次,而模式串pattern在每一次匹配中的走動均攤下來近似為O(m)的,因此總的複雜度為O(n+m)。

    下面貼上我的KMP演算法的模板,如果模式串在s中出現,則返回子串第一次出現的位置,否則返回-1。

#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>using namespace std;const int kMax1 = 1000010;const int kMax2 = 10010;char g_pattern[kMax2];char g_s[kMax1];int g_next[kMax2];void GetNext(int n){    memset(g_next, -1, sizeof(g_next));    g_next[0] = -1;    g_next[1] = 0;    int k = 0;    int i = 1;    while(i<(n-1))    {        //printf("i=%d, k=%d\n", i, k);        if(k == -1 || g_pattern[k] == g_pattern[i])        {            ++i; ++k;            g_next[i] = k;        }        else            k = g_next[k];    }}int KMP(int n){    int ans = -1;    int i = 0;    int j = 0;    int pattern_len = strlen(g_pattern);    while(i < n)    {        if(j == -1 || g_s[i] == g_pattern[j])        {            ++i; ++j;        }        else            j = g_next[j];        if(j == pattern_len)        {            ans = i - pattern_len;            break;        }    }    return ans;}

       該篇博文關於KMP演算法的理解和代碼,都是自己參照資料結構與演算法的書上面的一點理解。而代碼之前自己寫的方式不一樣,為了規範和容易閱讀,參考了網上的代碼,這個代碼肯定是沒有問題的,初學者可以放心的拿去當做模板使用。

    最後如果牛人發現了本博文存在紕漏,望牛人不吝賜教,我定當認真改過。




聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.