擴充套件KMP

2021-09-27 13:30:39 字數 3744 閱讀 8065

摘自 拓展kmp演算法總結

上圖中,s[k+1,k+len]=t[0,len-1],然後s[k+len+1]一定不等於t[len],因為如果它們相等,則有s[k+1,k+len+1]=t[k+po+1,k+po+len+1]=t[0,len],那麼next[k+po+1]=len+1,這和next陣列的定義不符(next[i]表示t[i,m-1]和t的最長公共字首長度),所以在這種情況下,不用進行任何匹配,就知道extend[k+1]=len

**2.2 ** 第二種情況:k+len>=p

**3、**至此,拓展kmp演算法的過程已經描述完成,事實上,計算next陣列的過程和計算extend[i]的過程完全一樣,將它看成是以t為母串,t為字串的特殊的拓展kmp演算法匹配就可以了,計算過程中的next陣列全是已經計算過的,所以按照上述介紹的演算法計算next陣列即可。

通過上面的演算法介紹可以知道,對於第一種情況,無需做任何匹配即可計算出extend[i],對於第二種情況,都是從未被匹配的位置開始匹配,匹配過的位置不再匹配,也就是說對於母串的每乙個位置,都只匹配了一次,所以演算法總體時間複雜度是o(n)的,同時為了計算輔助陣列next[i]需要先對字串t進行一次拓展kmp演算法處理,所以拓展kmp演算法的總體複雜度為o(n+m)的。其中n為母串的長度,m為子串的長度。

const

int maxn =

100010

;//字串長度最大值

int next[maxn]

, ex[maxn]

;//ex陣列即為extend陣列

//預處理計算next陣列

void

getnext

(char

*str)}}

//計算extend陣列

void

exkmp

(char

*s1,

char

*s2)

}}

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace std;

#define mem(a, b) memset(a, b, sizeof(a))

#define pi acos(-1)

#define debug(a) cout << (a) << endl

typedef

long

long ll;

int dir8[8]

[2]=

,,,,

,,,}

;int dir4[4]

[2]=

;const

int inf =

0x3f3f3f3fll

;const

long

long llf =

0x3f3f3f3f3f3f3f3fll

;const

int maxn =

2e5+15;

const

int mod =

1e9+7;

//priority_queue, vector>, greater>> q;

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

void

getnext

(string & t,

int& m,

int next)

else

next[i]

= next[i - a];}

}/* 求解 extend */

void

getextend

(string & s,

int& n, string & t,

int& m,

int extend,

int next)

else

extend[i]

= next[i - a];}

}int

main()

return0;

}

摘自 拓展kmp演算法總結

上圖中,s[k+1,k+len]=t[0,len-1],然後s[k+len+1]一定不等於t[len],因為如果它們相等,則有s[k+1,k+len+1]=t[k+po+1,k+po+len+1]=t[0,len],那麼next[k+po+1]=len+1,這和next陣列的定義不符(next[i]表示t[i,m-1]和t的最長公共字首長度),所以在這種情況下,不用進行任何匹配,就知道extend[k+1]=len

**2.2 ** 第二種情況:k+len>=p

**3、**至此,拓展kmp演算法的過程已經描述完成,事實上,計算next陣列的過程和計算extend[i]的過程完全一樣,將它看成是以t為母串,t為字串的特殊的拓展kmp演算法匹配就可以了,計算過程中的next陣列全是已經計算過的,所以按照上述介紹的演算法計算next陣列即可。

通過上面的演算法介紹可以知道,對於第一種情況,無需做任何匹配即可計算出extend[i],對於第二種情況,都是從未被匹配的位置開始匹配,匹配過的位置不再匹配,也就是說對於母串的每乙個位置,都只匹配了一次,所以演算法總體時間複雜度是o(n)的,同時為了計算輔助陣列next[i]需要先對字串t進行一次拓展kmp演算法處理,所以拓展kmp演算法的總體複雜度為o(n+m)的。其中n為母串的長度,m為子串的長度。

const

int maxn =

100010

;//字串長度最大值

int next[maxn]

, ex[maxn]

;//ex陣列即為extend陣列

//預處理計算next陣列

void

getnext

(char

*str)}}

//計算extend陣列

void

exkmp

(char

*s1,

char

*s2)

}}

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