Kmp演算法初析

2021-09-24 12:59:42 字數 2639 閱讀 8288

考慮字串匹配問題。

假設文字是乙個長度為n

nn的字串t

tt,模板是乙個長度為m

mm的字串p

pp,且m≤n

m≤nm≤

n。尋找匹配點使得t[i

]=p[

0]..

..t[

i+m−

1−1]

=p[m

−1]t[i]=p[0]....t[i+m-1-1]=p[m-1]

t[i]=p

[0].

...t

[i+m

−1−1

]=p[

m−1]

樸素方法:列舉起點,暴力比較,並且一旦不相同就退出。

複雜度:o(m

n)o(mn)

o(mn

)k mp

kmpkm

p具體操作為:求出每個點的字尾和開頭開始的字首最大相同區域是多少。

假如說aaa

abbb

bbaa

acaaaabbbbbaaac

aaaabb

bbba

aac開頭開始和結尾c往前(不包括c)開始最大相同區域為aaa,也就是說如果到了c失配,我可以直接從第4個a開始繼續匹配。(因為aaa已經匹配過了)。

這個時候回頭去看那張圖就很容易懂了。

如何求這個每個點的最大前字尾呢?

對於每個點,求出答案後,對於下乙個點如果相同的話,可以繼續擴大,否則的話迭代失配直到相同為止。

具體**:

#include

#define ll long long

#define inf 0x3f3f3f3f

using

namespace std;

char t[

1000060

],p[

1000050];

int f[

1000050];

void

getfail

(char

* p,

int* f)

}void

find

(char

* t,

char

* p,

int* f)

}int

main()

kmp

kmpkm

p中的字首陣列另乙個應用就是迴圈節:

因為k mp

kmpkm

p有個特殊性質。

y yy

yyxx

xyyy

yyyyyy***yyyy

yyyyyx

xxyy

yyy yy

yyxx

xyyy

y\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ yyyyy***yyyy

yyyyyx

xxyy

yy最大前字尾是這樣的形式。字首陣列求出來之後對於這種情況,從左到右可以分為abc

deabcde

abcd

e五個區域。

首先c

cc區域是一樣的,a=c

2=c1

=e,b

=′yx

xx′=

da=c_2=c_1=e,b='y***'=d

a=c2​=

c1​=

e,b=

′yxx

x′=d

那麼容易得到的是:a+b

=c2+

da+b=c_2+d

a+b=c2

​+d顯然這是是個迴圈節,最後的部分e

ee也一定是迴圈節的字首。

對於乙個字串,直接迭代求末尾的字首函式,就能求出所有迴圈節。(不過末尾可能只有迴圈節的點前面一小串)。

如果必須要求完全迴圈,那麼判斷是否滿足len

/(le

n−f[

x])len/(len-f[x])

len/(l

en−f

[x])

沒有餘數。迴圈節是上方的a+b

a+ba+

b區域。

迭代的一次求出的一定是最小迴圈節,因為此時字首陣列值最大。

例題:

#include

#define ll long long

#define inf 0x3f3f3f3f

using

namespace std;

char t[

1000060

],p[

1000050];

int f[

1000050];

void

getfail

(char

* p,

int* f)

}int

main()

}

KMP演算法小析

對於串的模式匹配演算法,相信學data structure的都不會很陌生,不過當我們看到各種書上對演算法kmp的講解時,我們會有種不知所云的感覺就算有的c 的演算法實現,和例子的講解,當換成另外乙個串時,我們將無從下手,其中對next的求解,更讓我們痛苦。在這裡sinpoal將自己對這個演算法的看法...

KMP演算法簡析

首先,kmp演算法是解決字串匹配問題的演算法,即在主串 s 中查詢子串 t。我們從問題入手,要在主串中查詢子串,顯然可以是用蠻力法逐個遍歷,即從主串的第乙個字元開始和子串的第乙個字元比較,若相等則繼續比較後續字元,若果不相等,則從主串的下乙個的字元 子串的第乙個字元重新開始比較。如果在主串遍歷完之後...

看毛片(KMP)演算法簡析

看毛片演算法又稱kmp演算法。該演算法之所以得名無外乎如下原因。每當涉及該演算法都甚新鮮,極想把玩一番,經過一番琢磨,終於悟透其本質。遂將其束之高閣,數月之後,再相邂逅,新鮮如初,又是一番把玩 醒悟 遺忘,如此迴圈以至無窮。足見,該演算法與看毛片的道理一脈相承。初看新鮮刺激,觀摩研究,醒悟不過如此而...