字串匹配之KMP演算法

2021-10-04 06:31:30 字數 3048 閱讀 3156

先不說演算法不演算法的的,怎麼知道乙個字串(模式串p)在是否在另乙個字串(字串t)中呢?序號1

2345

6789

10字串tab

cabo

kanp

模式串pab

cabd

正常的人就會想,我乙個乙個字元比對過去不久行了嗎,總結成思想就是

模式串p和字串t一位一位比,相同就往後比較,不同就移動一下模式串,繼續比

先看第0位,t[1]是a,p[1]也是a,即t[1]=p[1],那就接著比後面的,

再看第1位,t[2]是b,p[2]也是b,即t[2]=p[2],那就接著比後面的,

…再看第5位,t[6]是o,p[6]是d,即t[6]不等於p[6],字串匹配失效了,那就挪一下模式串p的位置,接著繼續比較,總的來說就是下面這樣的,正常人應該都能想到序號1

2345

6789

10字串tab

cabo

kanp

模式串pab

cabd

模式串pab

cabd

模式串pab

cabd

但是這樣的方法效率非常的低,一次一次的滑動,然後進行比較,時間複雜度為o(m

n)

o(mn)

o(mn

)。那有沒有其他的方法,序號1

2345

6789

10字串tab

cabo

kanp

模式串pab

cabd

我們可以看到在第6位的時候才發現匹配不對了,這說明前5位是匹配的,我們往後移動一位再跟字串t匹配。其實不用看目標串t,只看模式串p,我們也能夠「預知」接下來的第2次和第3次比較是肯定會失敗的。為什麼呢,下面說明一下

已知

t[1]

=p[1]t[

2]=p[2]t[

3]=p[3]t[

4]=p[4]t[

5]=p[5]t[

6]!=p[

6]

移動一位比較

t[

2]與p[

1]比較t[3

]與p[

2]比較t[4

]與p[

3]比較t[5

]與p[

4]比較t[6

]與p[

5]比較

進行簡單的轉換,t[1:

5]= p[1:

5],也就是說p[2

]與p[

1]比較p[3

]與p[

2]比較p[4

]與p[

3]比較p[5

]與p[

4]比較p[6

]與p[

5]比較

目標串

t[1] =a

t[2]=b

t[3]=c

t[4]=a

t[5]=b

t[6]=o

模式串p

p[1]=a

p[2]=b

p[3]=c

p[4]=a

p[5]=b

p[6]=d

模式串p

p[1] =a

p[2]=b

p[3]=c

p[4]=a

p[5]=b

p[1]不等於p[2],所以咱們就知道移動一位後還是會匹配失敗的。

再移動一位比較呢

t[

3]與p[

1]比較t[4

]與p[

2]比較t[5

]與p[

3]比較t[6

]與p[

4]比較t[7

]與p[

5]比較

進行乙個簡單的轉換,t[1:

5]= p[1:

5],也就是說p[3

]與p[

1]比較p[4

]與p[

2]比較p[5

]與p[

3]比較p[6

]與p[

4]比較p[7

]與p[

5]比較

發現p[3] != p1[1]進而可以直接推導出t[3] != p1[1],匹配會失敗序號1

2345

6789

10模式串pab

cabd

模式串pab

cabd

咱們想要把p直接多移動幾位,那該移動幾位呢,或者說該移動到**呢,再來手動試試找找感覺。

移動一位,p[1]!=p[2]->p[1]!=t[2],可以知道字串匹配不上序號1

2345

678模式串pab

cab模式串pab

cab移動兩位,p[1]!=p[3]->p[1]!=t[3],可以知道字串匹配不上序號1

2345

678模式串pab

cab模式串pab

cab移動三位,p[1]=p[4]->p[1]=t[4],字串匹配上了,而且p[2]=p[5]->p[2]=t[5],咱們直接比較p[3]跟t[6]就可以了。

目標串t序號12

3456

78模式串pab

cab模式串pab

cab可以很直觀的看到,如果字串字首和字串字尾相等,咱們就可以直接把字首對到字尾的位置,然後繼續比較後面的字元就可以了

目標串t序號12

ijnn+1

模式串p

p[1]

p[2]

…p[i]……

p[j]……

p[n]

模式串p和目標串t不匹配的字元位

模式串p

p[1]

p[2]

…p[i]

繼續比較t[n+1]和p[i+1]

為了不遺漏字元,這裡需要最長的公共前字尾,可以看一下大佬們的證明。可以看到,由原來的移動一位比較,現在可以直接移動j位了,並且,下一次比較可以直接從p[i+1]進行比較,因為1到i是匹配的。

字串匹配——sunday演算法

實現 strstr()

字串匹配之KMP演算法

以前零零散散做了些kmp的題目,一直也沒找出時間整理,這一段又開始研究字串了,就順便把kmp整理了一下。廢話不說了,我們直接入題。說到kmp,首先應該知道,它是一種字串查詢演算法,因為是由乙個姓k,乙個姓m和乙個姓p的人聯合發表的,所以就叫kmp演算法了。kmp演算法是一種線性時間的的字串匹配演算法...

演算法 字串匹配之KMP

說人話就是 比如有乙個字串 bbc abcdab abcdabcdabde 我想知道,裡面是否包含另乙個字串 abcdabd 許多演算法可以完成這個任務,kmp演算法是最常用的之一。首先對於上面的 比如 我們首先要針對搜尋詞 abcdabd 算出一張 部分匹配表 接下來就很簡單了,將字串和搜尋詞都從...

字串匹配之KMP演算法

問題定義 字串匹配即是在所有文字t中,找出模式p的所有出現。字串匹配常用的演算法有 樸素演算法 rabin karp演算法 有限自動機演算法 kmp演算法 所有演算法中,算kmp演算法效率最高。也較為難理解。作者曾經認真看了3遍嚴蔚敏的 資料結構 遺憾的是沒有看懂,搞得我一度懷疑自己的智商很低。今天...