KMP演算法講解

2021-07-15 11:09:49 字數 1628 閱讀 3764

第一次寫部落格有點小激動,今天要講一下kmp演算法,這個查詢演算法比較難理解,我也是想了很久才想明白,我們在str2中的pos位置開始查詢str1,當找到的時候返回str2中的下標,沒有找到的時候返回-1;首先我們來參考一下我們最初寫的查詢字串的函式,定義i=0為str2的下標,j=0為str1的下標,開始迴圈的時候,當遇到str2中的值,與str1中的值不同的時候,i變為最開始i前進的下乙個下標,j的下標變為0,不斷迴圈,知道i的值或者j的值大於他們的長度,然後再次判斷,如果j的值大於str1的長度,則i-j的值,就是在str2中找到的str1的位置,在此函式中i需要不斷地回退,因此時間複雜度比較大,在最大的時候會為o(n^2),因此我們用kmp演算法的乙個好處是i不需要回退,只需要把j回退到它該退的位置,j回退的位置,因此這樣的時間複雜度較低,為o(m+n)首先我們需要在str1中查詢兩個相同的真子串,第乙個真子串是str1的開頭作為開頭,第二個真子串是以剛剛匹配失敗的前乙個下標位置的作為結尾,每一次匹配失敗的時候我們都需要去查詢j該退回的位置,因此,定義乙個陣列來儲存在每乙個位置匹配失敗的時候j應該回退的下標,下面的bf()是我們初次寫的查詢字串的函式,getnext()函式是我們獲取乙個next陣列用來儲存每一次j需要退回的位置,getnextval()是根據得到的next再將j再次退到它直接應該回退的位置無論是利用getnext()或者getnextval()都能將j退回到該退的位置,然後從那個位置開始又與str2開始比較。

#include

#include

#include

#include

int bf(const char * str, const char *sub, int pos)

int i = pos;

int j = 0;

while (i < lena&&j < lenb)

else

}if (j >= lenb)

else }

static void getnext(char *next, const char *sub)

next[0] = -1;

next[1] = 0;

int j = 1;

int k = 0;

while (j < len-1)

else

}}static void getnextval(char *next, const char *sub)

next[0] = -1;

next[1] = 0;

int j = 1; //sub的下標

int k = 0;

while (j < len - 1)

else

}else

} }}

int kmp(const char *str, const char *sub, int pos)

int i = pos;

int j = 0;

char * next = (char *)malloc(lenb * sizeof(char));

getnextval(next, sub);

while (i< lena && j < lenb)

else

}if (j >= lenb)

else

free(next);

}

kmp演算法講解

kmp演算法本身,解決的是判斷模板字串t,是否是字串s的子串的問題。當只需判斷子串首次出現的位置,或是否包含子串。可以用庫函式strstr s,t 代替,判斷t是否為s的子串來代替。該函式的返回值是t首次出現的位置,如果t不是s的子串則返回null。該函式的複雜度與kmp類似。kmp演算法主要分為兩...

擴充套件kmp演算法講解

參考文章 一.擴充套件kmp得到的是什麼 字串a,b。b是模式串 子串 求解a i lena 1 與b的最長公共字首,記錄在陣列ex i 中 二.演算法實現 分為兩步,第一步是對b模式串進行處理也是求b i,blen 1 與b的最長公共字首,用next陣列儲存,第二部是將a與b進行匹配,其實他們的方...

KMP演算法入門講解

字串匹配問題。假設文字是乙個長度為 n 的字串 t 模板是乙個長度為 m 的字串 p 且 m leq n 需要求出模板在文字中的所有匹配點 i 即滿足 t i p 0 t i 1 p 1 t m 1 p m 1 的非負整數 i 注意字串下標從0開始 如圖所示,p 在 t 中有且只有乙個匹配點,即位置...