擴充套件KMP

2021-08-01 13:55:47 字數 1672 閱讀 8284

擴充套件 kmp 演算法

2017 年 03 月 12 日 • 閱讀: 256 • 技術

前文已經介紹了經典的 kmp 演算法,本文繼續介紹 kmp 演算法的擴充套件,即擴充套件 kmp 演算法。

問題定義:給定兩個字串 s 和 t(長度分別為 n 和 m),下標從 0 開始,定義extend[i]等於s[i]…s[n-1]與 t 的最長相同字首的長度,求出所有的extend[i]。舉個例子,看下表:

i 0 1 2 3 4 5 6 7

s a a a a a b b b

extend[i] 5 4 3 2 1 0 0 0

t a a a a a c

為什麼說這是 kmp 演算法的擴充套件呢?顯然,如果在 s 的某個位置 i 有extend[i]等於 m,則可知在 s 中找到了匹配串 t,並且匹配的首位置是 i。而且,擴充套件 kmp 演算法可以找到 s 中所有 t 的匹配。接下來具體介紹下這個演算法。

一:演算法流程toc

(1)如上圖,假設當前遍歷到 s 串位置 i,即 extend[0]…extend[i-1] 這 i 個位置的值已經計算得到。演算法在遍歷過程中記錄了匹配成功的字元的最遠位置 p,及這次匹配的起始位置 a。相較於字串 t 得出,s[a]…s[p] 等於 t[0]…t[p-a]。

再定義乙個輔助陣列int next,其中next[i]含義為:t[i]…t[m-1]與 t 的最長相同字首長度,m 為串 t 的長度。

(2)橢圓的長度為next[i-a],對比 s 和 t,很容易發現,三個橢圓完全相同。如上圖,此時i+next[i-a]

using namespace std;

/* 求解t中next,注釋參考getextend() */

void getnext(string t, int next)

else

next[i] = next[i - a];

}/* 求解extend */

void getextend(string s, string t, int extend, int next)

else

extend[i] = next[i - a];

}int main()

; int extend[100] = ;

string s = 「aaaaabbb」;

string t = 「aaaaac」;

getextend(s, t, extend, next);

//列印next和extend

cout << "next: " << endl;

for (int i = 0; i < t.size(); i++)

cout << next[i] << " ";

cout << "\nextend: " << endl;

for (int i = 0; i < s.size(); i++)

cout << extend[i] << " ";

cout << endl;

return 0;

}

三:時間複雜度toc

對比 kmp 演算法,很容易發現時間複雜度為 θ(n+m)。

—- 完 ヾ (^▽^*)))

下方可以給博主打賞哦☆⌒(*^- ゜)v thx!!

本作品採用知識共享署名 - 非商業性使用 - 禁止演繹 4.0 國際許可協議進行許可。

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...