KMP演算法初步學習

2021-08-28 04:20:51 字數 1781 閱讀 3659

用途

kmp演算法:它是用來匹配字串的,對於文字的檢索和查詢有很大的用處。說白了,它就是用來檢視乙個字串中是否包含有另外乙個字串,如果有,則返回第乙個字元的位置,否則返回-1,表示沒有找到。

簡單介紹

1. 當然,除了kmp匹配演算法,還有普通的字串匹配演算法,但是它的效率太低了,而kmp演算法則是進一步對普通方法的改進,可以顯著提高字串的匹配效率。首先先來介紹一下普通的字串匹配方法,通過比較來發現普通演算法和kmp演算法的不同。

普通匹配方法的基本思想是:讓模式串的第乙個字元與主串的第乙個字元比較,如果相等,則繼續比較後面的字元。如果和主串的第乙個字元就不相同,則繼續用模式串的第乙個字元和主串的第二個字元比較。這樣看起來似乎很合理,但是,如果模式串的前幾個字元都匹配成功,在後續字元的比較中有不同的,則下一次的比較,模式串仍然要回到第乙個字元,再去和主串比較。

下面用乙個例子來說明一下:

可見,這時比較到第三個字元的時候,出現了不同。

而下一次的比較中,模式串依然從第乙個字元開始和主串的第二個字元比較。

如果主串的長度為n,模式串的長度為m,則普通演算法的最壞時間複雜度為o(n*m)。

2. 而kmp演算法則使得模式串不用每次都回到第乙個字元,它會利用之前已經比較過的字元,從而確定下次比較從第幾個字元開始。

kmp演算法的核心就是確定每次匹配不成功時,下次比較開始的位置。

那麼怎麼確定這個位置呢?它是和匹配不成功時,所在字元的位置有關的。這個位置就是所在字元之前的所有字元的 字首和字尾 的最大相同長度。拿上面的例子來說,下次的開始的比較位置和模式串中下標0~2的字元有關。

什麼是字首和字尾的最大相同長度呢?在這之前,要先明白字首是什麼?字首就是乙個字串的前n個字元(0 < n < 字串的長度),即不包括它自身。比如:abababb的字首有:a、ab、aba、abab、ababa、ababab。字尾的意思和字首相反。字首和字尾的最大相同長度就是,先找出所有相同的字首和字尾,然後取其中長度最長的那一組。

比如:拿ababa來舉例,ababa中字首有:a、ab、aba、abab;字尾有:a、ba、aba、baba。那麼字首和字尾相同的有:a和aba,但是最大相同長度是aba。

明白了什麼是字首和字尾的最大相同長度後,我們用next陣列來記錄這個位置。即先求出模式串中所有子串的字首和字尾最大相同長度。

next陣列

模式串中與陣列(下標)對應的下標之前的字元

字首和字尾的最大相同長度

next[0]

null

-1next[1]a0

next[2]ab0

next[3]

aba1

next[4]

abab

2next[5]

ababa

3next[6]

ababab4

還拿普通演算法的例子來看一下,kmp演算法是如何匹配的:

可以發現,kmp演算法的下次比較位置不是0,而是1,而1也正是next[3]中所存的數。 小結

KMP初步理解

1.求pmt 由於我最開始學習的資料是用prefix的叫法,後來發先pmt更能表明。中也是使用之前的做法 public int prefix table else return prefix 為了方便,後移一位 不移,怎麼做 public void move prefix int prefix in...

KMP演算法學習

先貼上一點 等腦子清醒點再好好理解 求next陣列 public static int getnext string pattern else else return next public static int search string src,string pattern,int nextva...

KMP演算法學習

一 什麼是kmp演算法 knuth morris pratt 字串查詢演算法 常簡稱為 kmp演算法 是在乙個 主文字字串 s內查詢乙個 詞 w的出現,通過觀察發現,在不匹配 發生的時候這個詞自身包含足夠的資訊來確定下乙個匹配將在 開始 以此避免對以前匹配過的字元重新檢查。在原串中匹配模式串 二 k...