字串匹配 KMP演算法

2021-07-16 06:42:40 字數 1337 閱讀 1258

首先先來看乙個問題,給出兩個字串,s和t

問t在s中出現了多少次,不允許重複,但允許相互有相同部分。

首先想到的肯定是暴力,可以想到,從s的第乙個字元開始,看是否和t相等,然後向後移,統計有多少個相等,那麼時間就是o(

n×m)

當然,這個速度是非常慢的,如果兩個串的長度很長,或者有多組資料,自然就超時了。

顯然,在匹配的時候,如果遇到不相等的情況,移到下一位的時候,有很大的機率不會相等,那麼可以用乙個

next

陣列,記錄失配的時候,向右移幾位就可以讓前面的依然匹配。這就是kmp演算法的核心。

這時候就可以這樣做:

首先從第乙個字元開始,如果相等那麼向後匹配,如果失配那麼就跳到

next

位置。如果長度與t的長度相等,那麼計數器就加1

那麼,有了next,就很容易計算答案了,以下為**

int kmp()  

if (s[i] == t[k])

if (k == lent)

}return ans;

}

注意乙個很重要的東西:

next

在乙個庫中是乙個函式,最好不要呼叫,所以寫成了

_next

那麼,如何求

next

呢? 其實,求

next

也相當於是乙個在t之中與t匹配的樣子,先來看看**。

void get__next() 

if (t[i] == t[k])

_next[i]=k; // 記錄

}}

看起來和匹配很像對不對……

事實上,的確和匹配很像。

可以發現,

next

記錄的就是t的乙個字首的結尾和t的開頭最多能夠匹配的位數。匹配時,k記錄的就是s的字首和t的開頭能夠匹配的位數。

同時,求到k的時候,k前面的

next

都是求好的。

所以類似這樣的方法,去用t去匹配t,直接套用前面的匹配過程。

最後再分析一下時間複雜度。

既然它這麼神奇,

那麼時間複雜度肯定比o(

n×m)

要小,所以它的時間複雜度應該是線性的,於是來證明一下.

在匹配的時候,在s串中,k每一次

while

至少前進1,所以最多前進n次,而且最多會後退n次,因此匹配部分的時間複雜度應該為o(

n)那麼,求

next

類似,需要o(

m)的時間,所以最後總共需要o(

m+n)

的時間

這樣,kmp就順利地學完了……

KMP演算法 字串匹配

kmp演算法基本思想 我們在用常規的思想做 字串匹配時候是 如 對如 字元如果 t abab 用p ba 去匹配,常規思路是 看 t 第乙個元素 a 是否 和p 的乙個 b 匹配 匹配的話 檢視各自的第二個元素,不匹配 則將 t 串的 第二個元素開始 和 p 的第乙個匹配,如此 一步一步 的後移 來...

KMP字串匹配演算法

kmp核心思想 計算模式串的next陣列,主串的索引在比較的過程中不回朔 ifndef kmp h define kmp h class kmp endif include kmp.h include include include using namespace std int kmp calcu...

KMP字串匹配演算法

在介紹kmp演算法之前,先介紹一下bf演算法。一.bf演算法 bf演算法是普通的模式匹配演算法,bf演算法的思想就是將目標串s的第乙個字元與模式串p的第乙個字元進行匹配,若相等,則繼續比較s的第二個字元和p的第二個字元 若不相等,則比較s的第二個字元和p的第乙個字元,依次比較下去,直到得出最後的匹配...