關鍵點:公共前字尾字串
1.首先按照bf比較後,出現的那個不匹配的字元往前找,比如圖中是ab。每次要取最長公共前字尾字串,比如圖中最長的是ab。
2.然後,把最長字首移到最長字尾的位置,再從最長字尾開始比較。
這是按照移動模式串(子串)的思維來的。實際上操作是這樣:
每次開始比較的編號,等於最大公共前字尾長度+1
如圖中,到了模式串的第七個了,往前找,最大公共前字尾長度是1,這個時候把字首移到字尾的位置,即將1移到6,那麼接下來就是2號位與主串當前位比較。
前字尾長度為n,則n+1號位於主串當前位置比較這樣以來,就得到了next陣列。
比如剛才next[7]=2
前字尾長度為n,則n+1號位與主串當前位置比較前字尾長度為1,則2號位與主串當前位置比較,所以next[7]=2next[i]表示模式串中,前面長度為i的串的公共最長字首和字尾長度。一旦在匹配的時候在某個位置失配之後,直接依靠next陣列跳到相同字尾的字首部分。(相當於字尾的下乙個匹配失敗,則直接將位置跳到字首的部分,因為我們next陣列已經預處理了,o(1)實現。),
這時候繼續比較該位置和字首的下乙個字母是否匹配,不匹配繼續按上面的步驟跳轉,匹配則匹配下乙個字母直到完全匹配。
匹配失敗相當於字尾的下乙個匹配失敗了,我們就可以直接跳到與字尾相同的字首,此時前面依然是完全匹配的,繼續比較下乙個。
/*計算當前要匹配的模式串的next陣列*/
void
get_next
(string t,
int*next)
else
j=next[j]
;//若字元不相同,則j值回溯}}
/*執行kmp演算法*/
intindex_kmp
(string s,string t,
int pos)
else}if
(j>t[0]
)return i-t[0]
;else
return0;
}
普通的bf暴力比較:實現**:
/*返回子串t在主串s中第pos個字元後的位置。
*若不存在,則函式的返回值為0
**t非空,1<=pos<=strlength(s) */
intindex
(string s,string t,
int pos)
else}if
(j>t[0]
)return i-t[0]
;else
return0;
}
KMP 個人理解總結
這幾天複習kmp演算法,發現自己看別人的講解又看糊塗了,所以還是需要將別人的思想理解之後,自己再輸出一邊。kmp的出現是為了優化樸素模式匹配演算法,那麼樸素模式匹配演算法是什麼?又存在什麼缺點呢?樸素模式匹配演算法 複雜度o n m 就是將主串中與模式串長度相同的子串提取出來,挨個和模式串對比,當子...
KMP 演算法(個人理解)
相信大家看了 matrix67 的講解,一定已經知道了 kmp 演算法是怎麼回事,怎麼操作的,為什麼時間複雜度不高 這裡,我主要是分享我對 kmp 的理解 kmp 的精髓是什麼?這個東西,各自有個字的理解,很多人都覺得是避免了重複匹配,而我的理解是預處理 為什麼是預處理?你看看 kmp 的執行過程 ...
KMP演算法的個人理解
自學了一段時間,剛剛準備轉行做軟體開發,面試過程中被指出計算機基礎知識薄弱。因為是非科班出生,確實有些計算機方面的基礎沒有學過,也開始惡補這些方面的東西。最近在學習資料結構與演算法過程中,學到kmp演算法,甚是難解。看了阮一峰的網路日誌後才慢慢理解,但也發現其中的瑕疵,在此也順帶指出,至於對或不對,...