給定串s和t,求s的每乙個字尾和t的最長公共字首。
方法1:暴力演算法,時間複雜度o(n^2);
方法2:字尾陣列,利用height的性質可以求出該問題,時間複雜度為o(n),但是預處理為o(nlogn)
方法3:擴充套件kmp,充分利用已經匹配過的性質,降低匹配的時間,時間複雜度為o(n)
學習資料:
設next[i]為這樣乙個陣列,next[i]為串t的suffix(i)和suffix(0)的相似度,假設next[0-->k-1]已經算出了,並且在以前的匹配中,
匹配到的最遠處為p,如圖
假設是suffix(a)和suffix(0)匹配到最遠處p,那麼有t[a-->p] == t[0-->p-a+1]那麼這個匹配的後面一段也相等,即t[k-->p]==t[k-a-->p-a+1],
又因為next[k-a]是已知的,令l = next[k-a]
有兩種情況,
①k+l-1 < p, 那麼next[k] = l,不可能大於l,否則next[k-a] 就不等於l了, 可能有人會想到,為什麼表示k+l-1<=p,這個因為,如果取等號,那麼p+1的部分沒被判斷過,所以不能直接next[k] = l;
②k+l-1>=p, 那麼要重新匹配超過p的部分,即t[p+1] 和t[p-k+1]重新匹配。
九度oj 1535
1/*next[i] 表示t[i-->n]和t[0-->n]的相似度2*/
34 #include 5 #include
6const
int n = 1000000 + 10;7
char
s[n],t[n];
8int
next[n];
9int
extend[n];
10void
makenext()
1130
else
31 next[k] =l;
3233}34
35}36void
makeextend()
3756
else
57 extend[k] =l;58}
59}60int
main()
6174 printf("
%d\n
",ans);75}
76return0;
77 }
KMP 擴充套件KMP
本文將不斷加入例題,稍安勿躁,今天的總結爭取9 30寫完.kmp,中文名字叫字串匹配,用於解決一類字串匹配問題.先下一些定義 首先我們先想一想 nxt i 對於求解問題有怎樣的幫助.我們對於每乙個 t i s 1 的位置都匹配一次,這樣子複雜度為 theta n m 的.考慮在暴力匹配中其實我們不一...
擴充套件kmp
出自 2 i k l 1 p k,即i l p。這時,首先可以知道a i.p 和b 0.p i 是相等的 因為a i.p b i k.p k 而i k l 1 p k,由b 0.l 1 b i k.i k l 1 可得b 0.p i b i k.p k 即a i.p b 0.p i 然後,對於a p...
擴充套件KMP
拖了這麼久,終於打出擴充套件kmp了。並不長,但是細節很多。最好把模板背下來,實在背不下來就根據原理去推。相比於kmp來說擴充套件kmp的應用範圍更廣,更靈活。它的ext i 與kmp的next i 的區別就是next i 表示長度最大的一段s i next i 1 i t 1 next i ext...