模式匹配演算法 KMP演算法

2021-08-21 04:41:47 字數 1758 閱讀 4269

一.基本概念:

真字首指的是除了本身以外字串全部頭部的組合,真字尾指的是除了本身以外字串全部尾部的組合。

二.簡單的模式匹配演算法

按照正常的思維,字串可以進行暴力匹配,**如下。

int index_bf(string s,string p)

else

} if(j == p_len)

else

return -1;

}

暴力匹配的時間複雜度為o(mn),在處理大字串很難滿足我們的需求。

因此接下來介紹kmp演算法,時間複雜度為o(m+n)。

三.kmp演算法

3.1演算法流程

摘自部落格

(1)首先,主串"bbc abcdab abcdabcdabde"的第乙個字元與模式串"abcdabd"的第乙個字元,進行比較。因為b與a不匹配,所以模式串後移一位。

(2)因為b與a又不匹配,模式串再往後移。

(3)就這樣,直到主串有乙個字元,與模式串的第乙個字元相同為止。

(4)接著比較主串和模式串的下乙個字元,還是相同。

(5)直到主串有乙個字元,與模式串對應的字元不相同為止。

(6)這時,最自然的反應是,將模式串整個後移一位,再從頭逐個比較。這樣做雖然可行,但是效率很差,因為你要把"搜尋位置"移到已經比較過的位置,重比一遍。

(7)(8)i01

2345

67模式串abc

dabd

'\0'

next[i]-10

0001

20怎麼做到這一點呢?可以針對模式串,設定乙個跳轉陣列int next,這個陣列是怎麼計算出來的,後面再介紹,這裡只要會用就可以了。

(9)已知空格與d不匹配時,前面六個字元"abcdab"是匹配的。根據跳轉陣列可知,不匹配處d的next值為2,因此接下來從模式串下標為2的位置開始匹配

(10)

因為空格與c不匹配,c處的next值為0,因此接下來模式串從下標為0處開始匹配。

(11)

因為空格與a不匹配,此處next值為-1,表示模式串的第乙個字元就不匹配,那麼直接往後移一位。

(12)

逐位比較,直到發現c與d不匹配。於是,下一步從下標為2的地方開始匹配。

(13)

逐位比較,直到模式串的最後一位,發現完全匹配,於是搜尋完成。

3.2獲得next陣列

//得到next陣列 

void getnext(string p,int next)

else

}}

3.3kmp完整**

#include #include#includeusing namespace std;

const int n = 1005;

//得到next陣列

void getnext(string p,int next)

else }}

int kmp(string s,string p,int next)

else

} if(j == p_len)

else

}int main();

cout最後限於本人今天還有一丟丟事情沒做,以及kmp優化演算法的一些些的小缺陷,就先寫到這。

參考:

模式匹配 KMP演算法

字串匹配演算法 include includeusing namespace std define ok 1 define error 0 define overflow 2 typedef int status define maxstrlen 255 使用者可在255以內定義最長串長 typed...

模式匹配KMP演算法

前些日子在為目前該學習什麼而苦惱,就問了一下已經從事多年軟體開發的表哥,他說乙個程式設計師要走的遠,就要學好資料結構和演算法,於是我就重新開始學習資料結構和演算法了 拿起以前上過的資料結構看,看到第四章串的模式匹配時,頗感興趣,就寫了一下程式,實踐了一下。感覺還蠻爽,於是就把以下幾個重要的函式放在此...

KMP模式匹配演算法

首先,這是由knuth morris和prattle三人設計的線性時間字串匹配演算法。這裡就不仔細的講解,網上有更好的講解,在這推薦幾個自己當時學習的kmp所看到的較好理解的 這裡附上自己所學的 includeusing namespace std s 是主串 p 是模式串 int next 100...