判斷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...