KMP字串匹配

2021-07-12 00:08:48 字數 1511 閱讀 1936

判斷s中是否含有字串t。

一般思路為:從s中首字元開始,依次與t中進行比對,直到t結尾或者某乙個位置兩者不同 。如果到t的結尾,則表示s中含有t。如果有乙個位置不相同,那麼從s中下乙個字元開始,再次與t中字元比對。如下:

i = 0,j = 0;

for(;i= len)

}

這樣的比較,每一次遇到不同的時候都需要從t串的第乙個字元再次開始比較,因為最壞的時間複雜度為o(m*n)+——其中m,n分別表示s,t兩個字串的長度。kmp演算法避免了每一次都從t串的第乙個字元開始比較。

如下圖紅框部分——上面為s串,下面為t串:

執行到紅框位置時,t的下標為6,s的下標為8,

s與t的字元不相同。但在此之前的字串

"ruqwpr"

,s與t是相同的。kmp演算法正是利用了這一點對字串匹配進行了優化。

對於字串中的每乙個字元(記下標為x),都會存在一截字串,它的長度為n(可以為0),並且滿足條件一:

t[0]...t[n-1]與t[x-n+1]...t[x]相同

其中t[x-n+1]...t[x]表示從下標為x(含)處往前數n個字元組成的字串。當找不

到滿足條件一的字串時,記n為0,此時表示不存在相應的字串;並且對字串的首個字元來說,n也是0。我們可以將所有的n值

儲存於int next中。

對於某兩個字串的s與t來說,假設有s[i]!=t[j],那麼下一次可直接進行判斷s[i]與t[next[j-1]]是否相等。因為next陣列保證了s[i](不含)前面的next[j-1]個字元組成的字串與t[0]...t[next[j-1]-1]是完全相同的。例如abcdgabcdh,當匹配到h時,源串的格式必定是...abcdgabcd...,因此可以將abcdgabcdh移到成如下格式:

下一步要匹配的就是g是否與s[i]相等,而g的下標必定是next[j-1]。

上述的移動就是kmp演算法相對於普通匹配方法進行的優化地方。

**如下:

private static void next(int n, string p) 

if (p.charat(i) == p.charat(k)) else }}

具體的求解思路與kmp思路這一節完全一樣。

其具體思路與next陣列求解一樣。都是在某乙個字元不匹配時,將模板字元移動到next[pi-1]。

private static boolean kmp(string s, string p) 

continue;

}if (pi == 0) else

}return false;

}

kmp字串匹配

首先要對模式串進行預處理。預處理過程就是計算出指定位置的字首和字尾的最大相同的長度 啊啊啊啊。估計只有我乙個人能看懂 這個文章說得很清楚 比如說 a a a c b c a a a 0 1 2 0 0 0 1 2 3 void getnext int next,char par 20 int n 翻...

字串匹配 KMP

參考 從頭到尾徹底理解kmp 在字串 str 中 匹配模式串 pattern 1.計算模式串的 next 陣列 2.在字串中匹配模式串 當乙個字元匹配時,str i pattern k 繼續匹配下乙個字元 當當前字元不匹配時,根據 next 陣列移動模式字串,k next k next 陣列 描述模...

字串匹配 KMP

include include include using namespace std const intmaxn 10005 intf maxn void getf1 string p 可判斷週期及迴圈數 f i 1 p i p j j 1 0 for int i 1 i p.size i cou...