字串匹配 Kmp

2021-10-03 01:59:21 字數 2785 閱讀 3661

給定乙個主串 t

tt 和模式串 p

pp,求 p

pp 在 t

tt **現的下標。

我會暴力!

char t[n]

, p[n]

;scanf

("%s%s"

, t +

1, p +1)

;for

(int i =

1; i <=

strlen

(t +1)

; i++)if

(f)printf

("%d\n"

, i)

;else i = k;

// 如果匹配失敗,指標 i 回溯

}

我們用指標 i

ii 指 t

tt,指標 j

jj 指 p

pp。在暴力中,如果匹配失敗那麼 i

ii 和 j

jj 都會回溯到 111。

比如 t

=abbabbababaaababaaa,p

=abbabaababaa

t = \text, p =\text

t=abbabbababaaababaaa,p

=abbabaababaa

。讓 p

pp 去匹配 t

tt

abbabbababaaababaaa 	i from 1 to 6

abbabaababaa j from 1 to 6

!

第一次匹配中,j

jj 在第六位失配,但是 p

pp 的前五位abbab匹配成功了。暴力會讓 i

ii 回溯到 2

22,j

jj 回溯到 1

11,重新進行匹配。而我們要想辦法減少回溯。

那麼我們要利用已經匹配成功的前五位。可以發現abbab最長公共前字尾ab,這意味著 p

pp 的字首ab,可以與 t

tt 的字尾ab匹配,所以把 j

jj 回溯到字首ab的下一位也就是 ∣ab∣

+1=3

|\text| + 1 = 3

∣ab∣+1=

3。而 t

tt 中字尾ab的下一位為 i

ii 所以 i

ii 原地不動。

ab b ab bababaaababaaa i from 1 to 6

ab b ab aababaa j from 1 to 6

!abbabbababaaababaaa i from 6 to 10

abbabaababaa j from 2 + 1 = 3 to 7

!

為了實現剛才的演算法。我們需要預處理乙個 nxt

nxtnx

t 陣列,nxt

inxt_i

nxti

​ 為 t1∼

it_

t1∼i

​ 的最長公共前字尾的長度 +1+1

+1。我會暴力!

考慮 t

tt 匹配到了第 i

ii 位,這意味著求出了 nxt

i−

1nxt_

nxti−1

​。如果 t1,

i−1t_

t1,i−1

​ 的字首後面的字元等於 t

it_i

ti​,那麼 nxt

i=nx

ti−1

+1

nxt_i = nxt_ + 1

nxti​=

nxti

−1​+

1。

前 i - 1 位 abbabba

最長公共前字尾為 a

前 i 位 abbabbab

字首的下一位 = s 的第 i 位 = b

所以 nxt[i] = nxt[i - 1] + 1 = 2;

否則,考慮字首的字首和字尾的字尾,如果字首的字首的下乙個字元等於 t

it_i

ti​,那麼 nxt

i=nx

tnxt

i−1+

1nxt_ = nxt_} + 1

nxti​=

nxtn

xti−

1​​+

1。

前 i - 1 位 abaaaba

最長公共前字尾為 aba

前 i 位 abaaabab

字首的下一位 ≠ s 的第 i 位

字首的字首為 a

字首的字首的下一位 = s 的第 i 位 = b

所以 nxt[i] = nxt[nxt[i - 1]] + 1 = 2

#

include

using

namespace std;

const

int n =

1e6+5;

intread()

int nxt[n]

;char t[n]

, p[n]

;int nt, np;

void

getnxt()

}void

kmp()}

intmain()

kmp字串匹配

首先要對模式串進行預處理。預處理過程就是計算出指定位置的字首和字尾的最大相同的長度 啊啊啊啊。估計只有我乙個人能看懂 這個文章說得很清楚 比如說 a a a c b c a a a 0 1 2 0 0 0 1 2 3 void getnext int next,char par 20 int n 翻...

字串匹配 KMP

參考 從頭到尾徹底理解kmp 在字串 str 中 匹配模式串 pattern 1.計算模式串的 next 陣列 2.在字串中匹配模式串 當乙個字元匹配時,str i pattern k 繼續匹配下乙個字元 當當前字元不匹配時,根據 next 陣列移動模式字串,k next k next 陣列 描述模...

KMP字串匹配

判斷s中是否含有字串t。一般思路為 從s中首字元開始,依次與t中進行比對,直到t結尾或者某乙個位置兩者不同 如果到t的結尾,則表示s中含有t。如果有乙個位置不相同,那麼從s中下乙個字元開始,再次與t中字元比對。如下 i 0,j 0 for i len 這樣的比較,每一次遇到不同的時候都需要從t串的第...