查詢字串之 KMP演算法

2021-06-23 02:16:28 字數 1592 閱讀 4196

bf演算法中:

匹配串: ----a a a a b c c ---

模式串:-----a a a a a b c ---

後移後:------- a a a a a b c

在位置4匹配失敗,按照bf演算法,下一輪匹配開始,匹配串指標只會向後後偏移一位,

kmp 演算法是對bf演算法的改進,通過預處理,來改進每次向後的偏移量.

kmp演算法實在有點繞。看了很多文章都是描述不清,但這篇文章簡單易懂,強烈推薦。

內容不在贅述。對前字尾不明白的還可以看這篇文章。

對前字尾還有一種情況需要說明,那就是出現多個匹配項是取最長的匹配項:

比如: p =

p[0] = ,字首為 ,字尾為 只有空集匹配,那麼匹配值為length=0

p[1] = ,字首為 字尾為 出現了1個非空匹配項,匹配值為length = 1

p[2] = ,字首為 ,字尾為出現了兩個非空的匹配的,匹配值取max(length,length)=2

p[3] = ,字首為,字尾為,出現了3個非空的匹配項,匹配值取max(length,length,lenght) =3

p[4] = ,字首為 字尾為 只有空集匹配,匹配值為length = 0;

所以得到部分匹配表(partial match table ) pmt=

kmp演算法 其實只改進了bf演算法中一句(s++),增加後移偏移量。

kmp實現**如下:

int* kmp_build_pmt( const char* p ,int plen ) 	

} }return pmt;

}const char* kmp( const char* s , const char* p )

if ( !*p )

int plen = strlen( p );

int* pmt = kmp_build_pmt( p , plen );

char *s = (char*)s;

char *s1,*s2;

const char* match = null;

while( *s )

//s++;

//kmp 演算法相對於bf演算法,其實就只改了這一句!

//s2 == p 那麼 這次第乙個字元就失敗了,直接偏移1,同s++

//如果不等,s2 - p 表示匹配成功了多少個位元組。那麼本次偏移為 bias = 以匹配數量 - 對應部分的匹配值

//匹配串: a a a b c

//模式串: a a a c

//s2在c處失配,s2指向模式串的中c s2 - p = 3表示已匹配3個位元組, s2-p-1 表示最後乙個匹配字元的在模式串中的index(這裡是最後乙個a的index)

s += ((s2 == p) ? 1 : (s2 - p - pmt[ s2 - p - 1 ] ));

} delete pmt;

return match;

}

時間複雜度o(strlen(s)+strlen(p)).

空間複雜度o(strlen(p))

kmp 演算法和bf演算法都屬於字首匹配演算法。在實際使用中kmp效率並不會比bf效率高出多少。

KMP演算法查詢字串

使用kmp演算法查詢字串,時間效率為o m n include include include kmp演算法尋找字串匹配,時間效率為o m n void cmpnext const char pattern,int next next演算法 int main int argc,char argv e...

查詢字串之boyer moore演算法

給出字串p和t,長度分別為n和m。找出p在t中出現的所有位置。int index char p,char t,int pos else if j strlen p return i strlen p 1 else return 1 suffix tree演算法需要對字串t進行預處理,而boyer m...

查詢字串之 BF演算法

bf 演算法最簡單的查詢查詢字串演算法 匹配串s同模式串p,逐個位元組比較,失敗後向後移動乙個位元組繼續比較。直至成功或者比較結束。形如 a a a a 比較1 b b b b 比較2 b b b b 比較3 b b b b 這種方式簡單粗暴如其名 brute force 但是效率較低,用在比較短的...