void
getnext
(vector<
int>
& next, string s)
if(s[i]
== s[j]
) next[i]
= j;
}}
為什麼j按照上述的更新方法,是s[
0: i]這個字串中字首和字尾相等的最大字串的長度
j的更新方式:
如果s[i]
!= s[j] j一直回退(j = next[j -1]
),直到回退到s[j]
= s[i]
如果s[i]
== s[j] j = j +
1倒著推導:
i ⇒ 字尾末尾位置
j ⇒ 字首末尾位置
所以j是能匹配的最大字首的末尾位置的下標(1
)匹配過程中不等時, j通過回退來找到適合的最大字首(2
)當匹配相等時,j就是最大長度的下標,j+
1就是長度值
比如: aabaabaf
next[0]
=0;next[
1]即"aa"中(和字尾相等的)最大字首的位置的下標j=
0, next[1]
=1next[
2]即"aab"中沒有可以匹配的字首位置,j回退到0
,且不會加1
, next[2]
=0next[
3]即"aaba"中的最大字首匹配是j =
0,因為相等 j +
1= next[3]
=1next[
4]即"aabaa"中的最大字首匹配是j =
1,因為相等 j +
1= next[4]
=2next[
5]即"aabaab"中的最大匹配是j =
2,因為相等 j +
1= next[5]
=3next[
6]即"aabaaba"
,對比前j =
3, s[j]
='a'
, s[i]
='a'
, 因為相等, j +
1= next[6]
=4next[
7]即"aabaabaf"
, 對比j =
4, s[j]
='a'
, s[i]
='f'
, 因為不等, j = next[j-1]
= next[3]
=1s[j]
= s[1]
='a'
, 繼續不等, j = next[j-1]
= next[0]
=0,繼續不等, 退出查詢 next[7]
=0所以next =
這個時候可以思考為什麼不相等時,可以通過while不停的向前找(j = next[j -1]
)i是字尾末尾, j是字首末尾,
"aabaa"
, s[0:
3]="aaba"是字首, s[1:
4]="abaa"是字尾
如果s[j]和s[i]沒能匹配,最佳的策略是到前j個字串中縮小乙個範圍找到能和字尾匹配的
而next[j -
1]就是s[
0: j -
1]中能夠和字尾匹配的最大的長度,如果始終找不到匹配,就是0
暴力求解
#include
#include
using
namespace std;
intbruteforce
(string mains, string ss)}if
(j == ss.
size()
)}return-1
;}intmain()
kmp演算法
#include
#include
#include
using
namespace std;
void
getnext
(vector<
int>
& next, string s)
if(s[i]
== s[j])
next[i]
= j;}}
intkmp
(string mains, string ss, vector<
int> next)
else
i++;if
(j == ss.
size()
-1)}
return index;
}int
main()
KMP演算法Next陣列求解
相信對於kmp演算法本身大家都理解,最難理解的就是這個next陣列的求解了。這是 p 為模式串,下標從 0 開始 void getnext string p,int next else j next j 根據我的理解,i 和 j 可以看成是兩個指標,用來跟蹤當前匹配的位置。可以發現 i 是會不斷的往...
KMP演算法 快速求解next陣列
在kmp演算法中,最關鍵的就是求解next陣列了。那麼如何快速求解next陣列呢?已知模式串 ab cdabdd a 其next陣列 00 0 0 12 0 0 1 那麼是如何求證出來的呢?首先字串從左至右遍歷。第乙個字元a的next陣列對應元素為0,第乙個字元a和第2個字元b比,不相等。b 0 表...
KMP演算法中的next陣列求解
kmp演算法是在模式串的next陣列基礎上進行的,如何求解next陣列就成了關鍵。next陣列的求解和主串無關,只與模式串自身相關。則next j 1,當j 0時 max k 00,其他情況 比如對於p 5 c,next 5 2,因為 p0p1 p3p4 此時k 2。下面參考 資料結構 嚴蔚敏書中的...