*介紹:
kmp演算法是在給定的一串字串中查詢是否有目標串。
*分析:
1、一般解法
對於以上問題,假如用樸素演算法,我們容易想到:用目標串(長度為n)的第1個字元依次與給定串(長度為m)的第1個至最後乙個字元對齊匹配,直到找到目標串為止。這樣演算法複雜度是m*n。
2、kmp演算法:
思路分析:
kmp演算法通過建立乙個陣列(一般命名為next)來記錄目標串的自身特徵從而簡化匹配過程,令演算法的複雜度降至m+n。
舉例,假設目標串為: a b c a b c d d e a
對應next陣列的值為: 0 0 0 1 2 3 0 0 0 1
通過觀察我們會發現next陣列記錄的是以當前字元為字尾,以第乙個字元為字首的相同字串(這樣的字串可能有很多個)其中最長的乙個的長度。例如:對於例子中的第乙個b,以他為字尾,我們可以找到2個字串(ab,b) 以第乙個字元a為字首的字串也有3個(a,ab),由於從第1個字元到當前字元不再計算範圍之內所以最長長度為0;我們再看第2個b,以他為字尾的字串有(abcab,bcab,cab,ab,b),以第1個字元a為字首的字串有(a,ab,abc,abca,abcab)其中相同且最長的是ab這個字串所以next陣列的值為2。
知道next陣列是怎樣得出的之後我們進一步發現可以這樣理解:next陣列記錄的是與當前字元地位相當的字元的位置。例如,字串中的第2個b對應的next陣列值為2,我們由此考察字串中第2個字元恰好也是b,而且從第1個字元開始到我們找到的b為止的字串,與剛開始的b前面相應長度的字串完全一樣(都是ab),同樣我們可以考察其他字元,next陣列中的0則代表找不到乙個相當的字元。
分析到這裡我們自然想到:在字串的匹配過程中我們假如剛開始匹配的很好,而下乙個字元就不匹配了,我們就可以通過next陣列找到乙個字串來代替當前串繼續匹配,而不用像樸素演算法那樣回到開始。這正是kmp演算法省時間的原因。
關於next陣列的獲取:
我們得到next陣列取值的過程呢其實是在令next陣列內部與自身匹配,所以思路和以上極為相似。next陣列需要借助前面的取值來確定後乙個數的取值。假如當前字元(第2個b)和其前面的字元(第2個a)的next陣列指向的字元(第1個a)的後乙個字元(第1個b)相同,那麼當前字元的next陣列值就是前乙個字元next陣列值加1;假如不相同(例如第1個d),我們就需要以同樣的思路考察與當前字元前面的字元(第2個c)地位相當的字元(即next陣列指向的字元——第1個c),我們發現依然不相同並且此時已經沒有與第1個c地位相當的字元,所以next陣列的值只能是0。整個過程我們仍是在利用地位相當的字元,所以next陣列獲取的**與kmp演算法的主**非常像。
***:
#include#includeusing namespace std;
int next[1000],lent,lenp;
char text[1000],part[1000];
void get_next()//獲取next陣列
int main()
KMP演算法解題思路
bf暴力演算法進行模式匹配由於需要回溯,導致演算法效率低,kmp演算法對其進行改進的一點就是在某趟匹配失敗後,主串不進行回溯,而子串回溯到某乙個位置k。子串的每乙個位置都對應著乙個k,要找出這些值,首先列出子串所有的字首,分別對每個字首找出其最長公共前字尾 需注意,最長公共前字尾必須小於原字首且要相...
KMP演算法的思路闡述
思路 主串和模式串進行匹配,當主串i指標所指的值與模式串j指標所指的值不同,這時已經比較的模式串中,假設j前面的一段與模式串從下標為 0 開始的一段重合,則可以直接把指標j從j處移至k處,使此時的主串i指標指的值與j指的值比較。求next j 的意義 方便讓j指的模式串的值在任何時候與主串的值對不上...
拓展KMP分析
拓展kmp是對kmp演算法的擴充套件,它解決如下問題 定義母串s,和字串t,設s的長度為n,t的長度為m,求t與s的每乙個字尾的最長公共字首,也就是說,設extend陣列,extend i 表示t與s i,n 1 的最長公共字首,要求出所有extend i 0 i 注意到,如果有乙個位置extend...