擴充套件kmp

2021-09-07 23:13:00 字數 1201 閱讀 6596

問題描述

給定串s和t,設長度分別為n,m,依次計算出extend[0~n-1],extend[i]表示s的字尾s[i,n-1]與t的最長公共字首。

演算法描述

為了計算extend陣列,我們先計算乙個陣列next[0~m-1],next[i]表示t的字尾t[i,m-1]與t[0,m-1]的最長公共字首。

假設已經計算出了next陣列。現在借助於next陣列,從前向後計算s的每個位置的extend值。假設當前遍歷到位置i,即extend[0~i-1]都已經計算完。對於所有的$j\in [0,i-1]$,j對應乙個f(j)=j+extend[j]-1,設f(j)的最大值為p,取得p的位置為a,即p=f(a)。

s串: 0 1 2 … a … i-1 i … p …

對於a這個位置,有s[a,p]=t[0,p-a],那麼有s[i,p]=t[i-a,p-a]

要求extend[i],即s[i,n-1]匹配t[0,m-1],我們可以先用t[i-a,m-1]來匹配t[0,m-1],這正是next[i-a]表示的含義:t中位置i-a開始的字尾跟t的最長公共字首長度。令l=next[i-a],分以下兩種情況討論:

第一種 $i+l,如下所示。那麼有exend[i]=next[i-a](即l)。 

第二種 $i+l\geq p$,如下所示

p+1及其之後我們不知道是不是匹配,所以要逐個比較。

下面是計算extend的**。

1

void

getextend(

2const

char* s,const

intnslen,

3const

char* t,const

intntlen,

4const

int *next,

5int *extend)617

else extend[i]=next[i-a];18}

19 }

對於next的求法,顯然與上面是乙個過程,只是兩個串一樣:

1

void

getnext(

2const

char* s,const

intnslen,

3int *next)416

else next[i]=next[i-a];17}

18 }

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