因为自己是个菜B所以老实点复习算法
假设两个字符串
s
1
,
s
2
s1,s2
s1,s2.
需要找出
s
2
s2
s2在
s
1
s1
s1中出现次数(包含0次).
基本定义
n e x t i next_i nexti:在 s 2 1.. i s2_{1..i} s21..i中最长公共前缀后缀的长度.
匹配过程
(因为我懒得贴图所以只会口胡)
(贴个不错的博客忘记了就看这个)
http://www.ruanyifeng.com/blog/2013/05/Knuth–Morris–Pratt_algorithm.html
首先逐位匹配,如果遇到不匹配的,按照平时的匹配规律,我们应该是往后移一位然后重复匹配过程.
但是
k
m
p
kmp
kmp算法的优越之处就在于,它可以利用
n
e
x
t
next
next数组效率更高的往后跳转.
假设当前
s
2
1..
j
s2_{1..j}
s21..j均匹配,跳转方式为向后跳
j
−
n
e
x
t
[
j
]
j-next[j]
j−next[j]位.
原因:前文提到
n
e
x
t
next
next数组的定义为最长公共前缀后缀,所以跳转
j
−
n
e
x
t
[
j
]
j-next[j]
j−next[j]位就确保了前面的
n
e
x
t
[
j
]
next[j]
next[j]位仍然是匹配的,这就加快了匹配效率.
个人认为还是相当好理解.
如何 O ( n ) O(n) O(n)求 n e x t next next
其实跟上面的匹配过程同理.
设
k
k
k表示
s
2
1..
k
s2_{1..k}
s21..k和
s
2
i
−
k
.
.
i
s2_{i-k..i}
s2i−k..i相等.
若
s
2
k
+
1
s2_k+1
s2k+1相等
s
2
i
+
1
s2_i+1
s2i+1,则
k
+
+
k++
k++.
否则利用
n
e
x
t
next
next数组的性质,
k
=
n
e
x
t
[
k
]
k=next[k]
k=next[k]往前跳直至
s
2
k
+
1
=
=
s
2
i
+
1
s2_k+1 == s2_i+1
s2k+1==s2i+1.