全部資料結構、演算法及應用課內模板:
將kmp演算法,就要先講講它是用來幹什麼的,為什麼叫這個名字,暴力的演算法又是怎樣的
kmp是三人knuth,morris,pratt,他們仨發明了這個演算法,所以叫kmp。。。(不要驚訝。。)
然後它是用來解決字串的模式匹配問題(大白話就是找子串)
舉個例子說就是,給你乙個主串 s ,模式串 t,問你s裡含有多少個子串t,子串開頭下標多少
比如 s=aaaaa t=aa,於是有4個子串,下標分別是0,1,2,3
再比如
有1個子串,下標5
然後說一說暴力的演算法,也就是你沒學過kmp保證就那樣去寫了
叫做bf演算法,暴風(brute force)演算法(就是暴力啦~),是普通的模式匹配演算法
或者也可以叫做 *****strmatching 樸素的模式匹配演算法
暴力的方法事實上就是很單純的二重迴圈,s下標0開始,然後每次t下標0開始去和s比較
時間複雜度o(nm)
然後人們意識到,t每次向後挪一位很沒必要,然後從下標0開始一位一位地比較也完全沒必要
比如還是上面那個st
第一輪比較結果:
*****的暴力演算法接下來會比較:
並且挪到2號位的時候,t也會從0開始比較
這時候k、m、p三個人就開始研究人眼的匹配特性了
第一輪比較中,t匹配上的字首串是 : abab
這一串有 真字首串:a、ab、aba
真字尾串:b、ab、bab
他們發現,上述加粗的部分相同
於是規律性的東西出現了,我們再來看一下第一輪比較的圖
對於t t01=t23,然後看字尾23,s23=t23=t01
於是將 t01挪至s23,並直接比較s4和t2即可
所以,kmp演算法原理總結成一句話為:
比較失敗時,看已匹配成功的字首串a,取a的乙個真字尾串y,有乙個a的真字首串x與之相等
且此時lenx(=leny)長度盡可能長,將x挪至y的位置,直接比較x的下乙個字元和失敗位置的字元
不斷迴圈以上操作,直到無法繼續匹配
事實上,這個演算法還遠遠沒有說完
每次都現找字尾和與之對應的字首,時間又是很複雜
於是要先預處理出來對應位置儲存起來
比方說 abab 的 3號b 對應長度為 2(ab)
我們把這個稱之為特徵數n
對ababa有
於是這時我們再來看第一輪匹配
i=j=4時,匹配失敗,於是移動後 j=n[ j-1 ],接著比較 s[ i ] 與 t[ j ] 即可
當然,如果 j=0(第一位)就已經不相等了就沒有n[-1]了,就直接向後移動一位 i 就好
然後預處理特徵數n的時候如果太過暴力又會很慢
用動態規劃的思想去考慮,預處理這個東西的本質也是乙個kmp
比方說4號位的a,n[ 3 ]=2,於是直接 主:t[ 4 ] 和 模式:t[ 2 ]比較
發現 t[4]==t[2],於是 n[4]=n[3]+1=3,接著判斷第5位(當然上面這個串沒有5,那就結束了)
假設 t[ 4 ] != t[ 2 ],那麼就接著判斷當前真字首串的真字首串的下一位,就是去找判斷n[ n[ 3 ] - 1 ]即n[ 1 ]
然後不斷重複這樣的操作直到相等
當然,假設判斷到 0 還不相等,那麼 n[ 4 ]就=0
kmp演算法模板如下:(複雜度o(n+m))
char s[maxn],t[maxm]; //主串s,模式串t
int n,m,n[maxm],cnt; //主串長n,模式串長m,特徵數n,成功匹配個數cnt
vectorpos; //成功匹配位置所有下標(第乙個字元)
void get_next(){
m=strlen(t);
for(int i=1;ikmp演算法模板題:
可以交一發檢驗下自己寫的kmp對不對
KMP演算法總結與模板
發現學了好久了kmp了,模板卻總是背不會,感覺自己還是沒有理解深刻,僅以此作為複習 給定乙個模式串s長度為m,和模板串p長度為n,求解模板串p在模式串s 現的位置 模板串p需要同模式串s匹配很多次,當乙個字元匹配失效時,傳統的演算法往往模板串p會整個從頭開始,導致演算法的時間複雜度是o m n o ...
KMP演算法(模板)
time limit 1000ms memory limit 65536k 有疑問?點這裡 給定兩個字串string1和string2,判斷string2是否為string1的子串。輸入包含多組資料,每組測試資料報含兩行,第一行代表string1 長度小於1000000 第二行代表string2 長...
KMP演算法模板
在文字t 1.n 中找到某個模式p 1.m 所有出現的位置被稱作字串匹配問題 m n p3375 模板 kmp字串匹配 這道題在洛谷上的評級居然是普及 普及?qvq 實現起來還是比較簡單的,只不過有很多細節可以有很多種寫法,看別人的 容易凌亂。理解起來比較困難的部分是如何get next 不建議初學...