KMP詳解(這看不懂就沒辦法了 )

2021-07-23 21:31:41 字數 2076 閱讀 9201

我們在乙個母字串中查詢乙個子字串有很多方法。kmp是一種最常見的改進演算法,它可以在匹配過程中失配的情況下,有效地多往後面跳幾個字元,加快匹配速度。

當然我們可以看到這個演算法針對的是子串有對稱屬性,如果有對稱屬性,那麼就需要向前查詢是否有可以再次匹配的內容。

在kmp演算法中有個陣列,叫做字首陣列,也有的叫next陣列,每乙個子串有乙個固定的next陣列,它記錄著字串匹配過程中失配情況下可以向前多跳幾個字元,當然它描述的也是子串的對稱程度,程度越高,值越大,當然之前可能出現再匹配的機會就更大。

這個next陣列的求法是kmp演算法的關鍵,但不是很好理解,我在這裡用通俗的話解釋一下,看到別的地方到處是數學公式推導,看得都蛋疼,這個篇文章僅貢獻給不喜歡看數學公式又想理解kmp演算法的同學。

位置i字首next[i]子串a

gcta

gcag

ctag

ctg申明一下:下面說的對稱不是中心對稱,而是中心字元塊對稱,比如不是abccba,而是abcabc這種對稱。

(1)逐個查詢對稱串。

這個很簡單,我們只要迴圈遍歷這個子串,分別看前1個字元,前2個字元,3個... i個 最後到15個。

第1個a無對稱,所以對稱程度0

前兩個ag無對稱,所以也是0

依次類推前面0-4都一樣是0

前5個agcta,可以看到這個串有乙個a相等,所以對稱程度為1前6個agctag,看得到ag和ag對成,對稱程度為2

這裡要注意了,想是這樣想,程式設計怎麼實現呢?

只要按照下面的規則:

a、當前面字元的前乙個字元的對稱程度為0的時候,只要將當前字元與子串第乙個字元進行比較。這個很好理解啊,前面都是0,說明都不對稱了,如果多加了乙個字元,要對稱的話最多是當前的和第乙個對稱。比如agcta這個裡面t的是0,那麼後面的a的對稱程度只需要看它是不是等於第乙個字元a了。

b、按照這個推理,我們就可以總結乙個規律,不僅前面是0呀,如果前面乙個字元的next值是1,那麼我們就把當前字元與子串第二個字元進行比較,因為前面的是1,說明前面的字元已經和第乙個相等了,如果這個又與第二個相等了,說明對稱程度就是2了。有兩個字元對稱了。比如上面agctag,倒數第二個a的next是1,說明它和第乙個a對稱了,接著我們就把最後乙個g與第二個g比較,又相等,自然對稱成都就累加了,就是2了。

c、按照上面的推理,如果一直相等,就一直累加,可以一直推啊,推到這裡應該一點難度都沒有吧,如果你覺得有難度說明我寫的太失敗了。

當然不可能會那麼順利讓我們一直對稱下去,如果遇到下乙個不相等了,那麼說明不能繼承前面的對稱性了,這種情況只能說明沒有那麼多對稱了,但是不能說明一點對稱性都沒有,所以遇到這種情況就要重新來考慮,這個也是難點所在。

(2)回頭來找對稱性

這裡已經不能繼承前面了,但是還是找對稱成都嘛,最愚蠢的做法大不了寫乙個子函式,查詢這個字串的最大對稱程度,怎麼寫方法很多吧,比如查詢出所有的當前字串,然後向前走,看是否一直相等,最後走到子串開頭,當然這個是最蠢的,我們一般看到的kmp都是優化過的,因為這個串是有規律的。

在這裡依然用上面表中一段來舉個例子:   

位置i=0到14如下,我加的括號只是用來說明問題:

(a g c t a g c )( a g c t a g c) t

我們可以看到這段,最後這個t之前的對稱程度分別是:1,2,3,4,5,6,7,倒數第二個c往前看有7個字元對稱,所以對稱為7。但是到最後這個t就沒有繼承前面的對稱程度next值,所以這個t的對稱性就要重新來求。

這裡首要要申明幾個事實

1、t 如果要存在對稱性,那麼對稱程度肯定比前面這個c 的對稱程度小,所以要找個更小的對稱,這個不用解釋了吧,如果大那麼t就繼承前面的對稱性了。

2、要找更小的對稱,必然在對稱內部還存在子對稱,而且這個t必須緊接著在子對稱之後。

如下圖說明。

從上面的理論我們就能得到下面的字首next陣列的求解演算法。

void

setprefix(const

char *pattern, int prefix)

}通過這個說明,估計能夠理解kmp的next求法原理了,剩下的就很簡單了。我自己也有點暈了,實在不喜歡那些數學公式,所以用形象邏輯思維方法總結了一下。

完全看不懂的KMP演算法

kmp演算法 當我第一次接觸kmp演算法的時候我是懵逼的,看著眼前乙個字串的題目愣是莫得思路,後來我接觸到了kmp演算法,然後 然後就更懵逼了 kmp 演算法,該演算法相對於 brute force 暴力 演算法有比較大的改進,主要是消除了主串指標的回溯,從而使演算法效率有了某種程度的提高。int ...

電視盒子的世界,你看不懂就對了

多少人是盯著瀏覽器裡模糊的畫面看比賽的?若嚴格按規定執行,盒子就廢掉了。現在最好的辦法是用電腦瀏覽器開啟 cntv 購買比賽高畫質直播服務包,然後通過 hdmi 線,將電腦螢幕拓展到電視螢幕上。太麻煩。難道不能在盒子裡不花錢看標清的比賽直播嗎?當然不能,cctv 5 又不是免費的公共頻道,平常也得交...

Git超詳解一 基本配置 (看不懂算我輸)

3.身份配置 4.修改預設編輯器 5.重新進行配置 6.補充 git init1.系統級別 git安裝路徑 etc gitconfig使用者級別 c users user gitconfig。倉庫級別 git config系統級別 etc gitconfig使用者級別 gitconfig 或 con...