關於KMP匹配模式演算法的小結

2021-09-30 15:48:23 字數 1553 閱讀 2683

關於串的匹配模式演算法有兩種:

1.樸素模式匹配演算法(也稱為暴力破解演算法)

2.kmp模式匹配演算法(有未優化版的和優化版兩種)

下面開始介紹兩種模式匹配演算法:

在串的模式匹配中,例如主串abcdabef中找子串abe,我們能想到的最簡單的演算法就是利用兩個變數i和j,加上兩個巢狀的for迴圈,i用於指定主串字元,j用於指定子串字元例如

for(i=0;i<=m-1;i++)  //m為主串的長度

for(j=0;j<=n-1;j++) //n為子串的長度

execute statement //匹配後的執行語句

這種可以稱為在數學上叫迴圈式列舉法來進行全比較的模式匹配演算法,也就是我們所說的樸素模式匹配演算法。

該演算法滿足解決問題的演算法定義要求,但該演算法卻有著比較複雜的時間複雜度o(m*n),但是經過研究我們可以發現,這個演算法其實是可以優化的,而這個優化後的演算法就是kmp模式匹配演算法。

kmp模式匹配演算法中的kmp是三個人名中的英文本母開頭,kmp的演算法思想是在i++ j++上做優化,也就是對i和j的定位做出優化,減少可預見的無效的i++ j++定位次數,從而減少演算法的時間複雜度達到乙個優化的效果。那麼kmp演算法是如何來進行i j的從新定位的呢?

當在每次匹配失敗時i的值保持不變,j根據乙個next(j)函式來取值。getnext(j)是乙個根據j值變化定義的陣列,求的是在模式串位置j處前面的最大相同前字尾長度,並且next陣列的長度就是模式串的長度。下面是getnext()的推導方法:

在推導之前我們必須要先了解一下什麼是乙個字串的真字首和真字尾,以abacaba為例,其相同前字尾有a和aba,最大相同前字尾就是aba長度為3。那麼如何去確定在模式串中每個位置所對應的最大相同前字尾的值呢?

首先了解一下next的函式定義:

next()實現函式的**如下:

void getnext(string t,int *next){

int i,j;

i=1;

j=0;

next[1]=0;

while(iif(j==0 || t[i]==t[j])  //t[i]表示字尾的單個字元 t[j]表示字首的單個字元

++i;++j; 

next[i]=j; //字元相同的話就自增,尋找下乙個相同的值,並且把j的值賦給next[i]

else

j=next[j];//若字元不相同則j值回溯

該段**計算出當前要匹配串t的next[i]陣列,此時就可以描述kmp模式匹配演算法了,在樸素模式匹配演算法的基礎上,當兩個字元不相等時,對i 和j的處理由原來的i++和j++改寫為i不變且j根據next陣列來確定j的值。

kmp模式匹配演算法的改進:

當next陣列在進行字首字元與字尾字元進行比較的時候,如果字首字元與字尾字元相同,這個時候就可以把字首字元位置的next值賦值給字尾字元位置的next值,就不需要重複計算。

模式匹配 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...