3算法全称_全网最通俗的KMP算法图解
導語
本篇內容研究字符串匹配問題,首先介紹字符串匹配問題,引出Brute-Force算法及其優化方法,最后深入詳解KMP算法。文章結構如下(全文閱讀需要30分鐘左右):
字符串匹配問題
1字符串匹配問題是什么
"字符串A是否為字符串B的子串?如果是的話出現在B的哪些位置?"該問題就是字符串匹配問題,字符串A稱為模式串,字符串B稱為主串。
2應用
字符串匹配應用很廣泛,比如你想在一篇文章中找到某個關鍵字所在的位置,或者是你想在一份名單中找到某個名字是否出現等等
Brute-Force算法
1算法核心思想
Brute-Force算法簡稱BF算法(并不是Boy Friend),算法的核心思想跟名字一樣粗暴,如下所示:
2python代碼實現
假設n為主串長度,m為模式串長度。每一輪字符串比較:最差的情況為模式串最后一個字與主串不同其他都相同(如模式串為AAB,主串對應部分為AAC),必須走完整個字符串才能得出結果,因此復雜度為O(m)。所有輪字符串比較:最差的情況是移動到最后一次比較才尋找得到,總共需要n-m+1次,主串通常比模式串長很多,故Brute-Force時間復雜度為O(nm)
3算法優化思路
最壞的情況:
兩個字符串是否相同的比較很難優化,只能逐字比較。然而比較的趟數是可以減少的,因此盡可能減少比較的趟數是算法優化的方向,也是KMP算法的核心思想。那么,讓我們開始KMP算法的講解。
KMP算法詳解
KMP算法于1977年被提出,全稱 Knuth–Morris–Pratt 算法,包含了三位前輩名字,分別是:Donald Knuth(K), James H. Morris(M), Vaughan Pratt(P)01算法核心思想
如何減少匹配的趟數呢?其實在每一次匹配過程中,我們就能夠判斷后續幾次匹配是否會成功,算法的核心就是每次匹配過程中推斷出后續完全不可能匹配成功的匹配過程,從而減少比較的趟數,如圖所示:
因此,第一次匹配過之后,就可以得出可以直接跳到第四趟再進行判斷的結論了。因為第一次匹配的時候,前5個序列和主串相同,只需要對模式串進行分析,模式串出現了重復單元(即AB),在第一次匹配失敗后就可以直接跳躍到出現重復單元的位置。
2next數組
next數組實質上就是找出模式串中前后字符重復出現的個數,為了能夠跳躍不可能匹配的步驟。
next數組的定義為:next[i]表示模式串A[0]至A[i]這個字串,使得前k個字符等于后k個字符的最大值,特別的k不能取i+i,因為字串一共才i+1個字符,自己跟自己相等毫無意義。
最終得到next數組為:
如何確定在移動過程中需要跳過多少步呢?下圖更直觀的體現了跳躍的過程:
對于上述紅色部分的計算跳過長度的公式為跳過的趟數=匹配上字符串中間字符長度-重復字符串長度
跳過這些步驟后并非再從頭開始匹配,而是從重復位置開始匹配:
最終,我們不難得出如下結論:
3python代碼實現
1.首先建立KMP對象,初始化參數:
2.建立next數組:
第一種最簡單的構建方案,時間復雜度為O(m平法):
第二種構建方案,是一種遞推的方式進行構建,時間復雜度為O(n+m):
考慮:如果next[0], next[1], ... next[x-1]均已知,那么如何求出 next[x] ?我們已經知道next[x-1],標記next[x-1]=temp,則可以討論A[temp]和A[x]的值,分2種情況討論:
第一種情況:A[temp]等于A[x],也就是說在前一個next結果上又多了一個字符串相同的長度,因此next[x]為next[x-1]+1
第二種:當A[temp]和A[x]不相等的時候,我們需要縮小temp,把temp變成next[temp-1],直到A[temp]=A[x]為止。A[now]=A[x]時,就可以直接向右擴展了。
遞推構建next數組代碼如下:
3.檢索過程代碼:
4.測試代碼:
作者原創,未經授權請勿轉載
總結
以上是生活随笔為你收集整理的3算法全称_全网最通俗的KMP算法图解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 电脑找不到MSVCR100.dll如何解
- 下一篇: 10投屏后没有声音_手机投屏到电视没有声