此演算法的關鍵是求next(j);
若設在進行某一趟匹配比較時在模式p的第j位失配,
如果j=0,則目標串指標t進一,模式串指標p回到p0p0
,繼續進行下一趟匹配比較。
知道了next陣列怎麼使用後,再介紹kmp演算法的原理。
樸素模式匹配速度慢的原因是有回溯,而這些回溯是可以避免的。例如:
ta b b a b a
pa b a
第一趟比較,t0 = p0,t1=p1,t2
≠ ≠
p2,但p0
≠ ≠
p1,由此可推知t1(=p1)
≠ ≠
p0,將p右移一位,用t1和p0比較肯定不等,這一趟可以不比較。又由於p0=p2,所以t2
≠ ≠
p0 (p0=p2),將p再右移一位,用t2和p0比較也不會相等。我們應該將p直接右移3位。從t3和p0開始進行比較。這樣的匹配過程對於t來說就消除了回溯。
如果有從目標t的第s個位置ts
t
s與模式p的第0個位置p0
p
0開始進行比較,直到在目標t第s+j位置ts
+jt s+
j」失配」,這時應有:ts
ts+1
ts+2
...t
s+j−
1=p0
p1p2
...p
j−1 tst
s+1t
s+2.
..ts
+j−1
=p0p
1p2.
..pj
−1
按樸素模式匹配演算法,下一趟應從目標t的第s+1個位置起用ts
+1t s+
1於模式p中的p0
p
0對其,重新開始匹配比較。若想匹配,必須滿足:ts
+1ts
+2ts
+3..
.ts+
j...
ts+m
=p0p
1p2.
..pj
−1..
.pm−
1 ts+
1ts+
2ts+
3...
ts+j
...t
s+m=
p0p1
p2..
.pj−
1...
pm−1
如果在模式串p中,p0
p1p2
...p
j−2≠
p1p2
...p
j−1 p0p
1p2.
..pj
−2≠p
1p2.
..pj
−1
則第s+1趟不用進行匹配比較,就能斷定它必然「失配」。
依此類推,直到對於某乙個值k,使得:p0
p1p2
...p
k+1≠
pj−k
−2pj
−k−1
...p
j−1 p0p
1p2.
..pk
+1≠p
j−k−
2pj−
k−1.
..pj
−1
且 p0p1p
2...
pk=p
j−k−
1pj−
k...
pj−1
p 0p
1p2.
..pk
=pj−
k−1p
j−k.
..pj
−1
才有 p0p
1p2.
..pk
=ts+
j−k−
1ts+
j−k.
..ts
+j−1
p 0p
1p2.
..pk
=ts+
j−k−
1ts+
j−k.
..ts
+j−1
這樣,可以把在某趟比較「失配」時的模式p從當前位置直接向右滑動j-k-1位。
可以從t中的ts
+1t s+
1(即上一趟失配的位置)與模式串的pk
+1p k+
1開始,繼續向下進行比較。
用乙個next特徵函式來確定:當模式p中的第j個字元與目標串t中相應的字元失配時,模式p中應當由哪個字元(設為第k+1個)與目標中剛失配的字元重新繼續進行比較。
public static int next(string pat) else
}
return
next;
}
public static int kmpmatch(string tar,string pat)
else p = next[p];
}if (p < plen) return -1;
else
return t-plen;
}
public
static
void
main(string args)
acabaabaabcacaabc
abaabcac
kmp匹配結果:5
next陣列為:
-1 0 0 1 1 2 0 1
總結:kmp為無回溯的演算法,在計算next過程中,實際上也是乙個模式匹配的過程,只是目標串和模式串現在是同乙個串p,也是無回溯的過程。kmp演算法的時間複雜度為o(lengtht+lengthp)。
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的第乙個字元,依次比較下去,直到得出最後的匹配...