演算法筆記 字串匹配KMP演算法,簡單易懂

2021-10-25 03:16:38 字數 2991 閱讀 6489

kmp演算法看懂了就會感覺挺容易的,思路也很清晰。看不懂就會稀里糊塗。

先說什麼是字串匹配

字串匹配。簡單來說,就是給你兩個字串,尋找其中乙個字串是否包含另乙個字串,如果包含,返回包含的起始位置。

比如下面兩個字串:

string s1=

"bacbababadababacacabc"

;string s2=

"ababaca"

;

s1中包含s2,在s1下標10處;

bacbababadababacacabc

再說說kmp演算法

看完字串匹配,你可能想到的可能是拿s1的首位與s2的首位比較,相等就s1和s2都後移一位,不相等s1就後移一位s2返回到第一位。

當然想到這種演算法思想是很好的,但時間複雜度你算一下,如果s1有n位,s2有m位,最倒霉的情況(就是查到最後才查到),迴圈就執行了(m-n+1)*n次,這樣時間複雜度就是o(m * n)。

想必你也看出來了,時間複雜度之所以那麼大,是因為它逐步查詢太慢了,可不可以讓它一下移動好幾位,kmp演算法就做到了這一點,這樣kmp演算法就可以實現時間複雜度為o(m+n)

kmp演算法分為兩大塊,next陣列構造和kmp函式構造。

1、next陣列構造

next陣列是針對s2,也就是子串構造的乙個轉移函式。其含義就是乙個固定字串的最長字首和最長字尾相同的長度。(這一點一定要記清,即使**不會,next函式也一定要明白怎麼構建)。

普及一下最長相同字首和字尾的含義。

最長字首:是說以第乙個字元開始,但是不包含最後乙個字元。

最長字尾:以最後乙個字元開始,但是不包含第乙個字元。

比如 ababa

字首有a ab aba abab

字尾有baba aba ba a

最長字首就是abab,最長字尾就是baba,最長相同字首和字尾就是aba

next陣列記錄的就是最長相同字首和字尾,這裡就是3

言歸正傳,繼續說next陣列:

比如這裡的s2,ababaca;長度是7,所以就有了next[0]next[1]next[2]next[3]next[4]next[5]next[6]

注意此版本的next [ i ] 這裡是看前 i 位的最長相同字首和字尾。版本不同,next陣列也不同,不過是相同的邏輯。(比如史老師的課上講的next陣列就是在此版本的基礎上+1)

首先是next[0],初始讓next[0]=-1(第乙個數特殊,後面講kmp時會提到) 。

next[1]就是求a的最長相同字首和字尾,這裡是" ",沒錯就是空,所以next[1]=0。

next[2]對應 ab,對應" ", next[2]=0。

next[3]對應 aba,對應"a",next[3]=1。

next[4]對應 abab,對應"ab",next[4]=2。

next[5]對應 ababa,對應"aba", next[5]=3。

next[6]對應 ababac,對應" ", next[6]=0。

所以next陣列這裡就是next[0]=-1

next[1]=0,next[2]=0,next[3]=1,next[4]=2,next[5]=3,next[6]=0。

2、kmp函式的構造

kmp函式就是拿s2函式和next陣列與s1進行比較,next陣列就是讓s1盡可能多地「滑動」。

再拿來這倆字串

string s1=

"bacbababadababacacabc"

;string s2=

"ababaca"

;

首先拿s1的第一位與s2的第一位進行比較,如果第一位都不相同,那s1直接後移一位,s2重新從第一位開始(因為是第一位都不相等,這裡特殊標記了一下,這就是next [ 0 ] = -1d的原因)。

如果第一位相同,看第二位,第二位不相同,那s2就返回第(next [ 1 ] 的值)的位置再繼續比較s1的第二位和s2的第(next [ 1 ] 的值)的位置,如果還不相等s2就繼續往前移…最壞的情況是前移到s2的第一位,這樣的話就是上一段所講的next[0]的情況了

第一位,第二位,第三位…

直到s2比到最後一位,如果相等就返回當前s1位置減去s2長度加1,就是匹配字串的初始位置。

那如果s1比到最後一位時s2還是沒能匹配到最後一位,那就是沒找到匹配字串

(其實你可以看一下,s2前移的過程就是s1往後滑動的過程,s2前移幾位,s1就後滑幾位)

**實現

全域性變數

string s;

int nxt[

10000

];

getnxt()函式

void

getnxt()

else

k=nxt[k]

;//回溯

}}

kmp函式

int

kmp(string ss)

else

j=nxt[j]

;//回溯}if

(j==len2)

//匹配成功

return i-j+1;

else

//匹配失敗

return-1

;}

main函式

int

main()

如果看不懂的話,這裡推薦一篇部落格

超級詳細,再看不懂我就吃電腦

就到這裡了拜拜ღ( ´・ᴗ・` )比心

字串匹配演算法 KMP演算法

kmp演算法是一種改進的字串匹配演算法。kmp演算法的關鍵是利用匹配失敗後的資訊,儘量減少模式串與主串的匹配次數以達到快速匹配的目的。具體實現就是實現乙個next 函式,函式本身包含了模式串的區域性匹配資訊。下面從乙個例子來了解kmp演算法 字串 bbc abcdab abcdabcdabde 我想...

字串匹配演算法KMP演算法

資料結構中講到關於字串匹配演算法時,提到樸素匹配演算法,和kmp匹配演算法。樸素匹配演算法就是簡單的乙個乙個匹配字元,如果遇到不匹配字元那麼就在源字串中迭代下乙個位置乙個乙個的匹配,這樣計算起來會有很多多餘的不符合的匹配做了冗餘的比較。假設源字串長n,字串長m 該演算法最差時間複雜度為 m n m ...

字串匹配演算法(KMP演算法)

力扣 實現 strstr 函式。給定乙個 haystack 字串和乙個 needle 字串,在 haystack 字串中找出 needle 字串出現的第乙個位置 從0開始 如果不存在,則返回 1。int strstr char haystack,char needle else if j n len...