Python 實現 KMP 演算法
Haystack :需要搜尋給定模式的字串。
針 :要搜尋的模式。
時間複雜度 :搜尋部分(strstr 方法)具有複雜度 O(n)
,其中 n
是 haystack 的長度但是針也被預先解析為構建字首表 O(m)
是構建字首表所必需的,其中 m
是長度針。
因此,KMP 的總時間複雜度為 O(n + m)
空間複雜度 : **O(m)
,**因為針上有字首表。
注意:以下實現返回 haystack 中匹配的起始位置(如果匹配)else 返回 -1,對於邊緣情況,例如,如果 needle / haystack 是空字串或在 haystack 中找不到針。
def get_prefix_table(needle):
prefix_set = set()
n = len(needle)
prefix_table = [0]*n
delimeter = 1
while(delimeter<n):
prefix_set.add(needle[:delimeter])
j = 1
while(j<delimeter+1):
if needle[j:delimeter+1] in prefix_set:
prefix_table[delimeter] = delimeter - j + 1
break
j += 1
delimeter += 1
return prefix_table
def strstr(haystack, needle):
# m: denoting the position within S where the prospective match for W begins
# i: denoting the index of the currently considered character in W.
haystack_len = len(haystack)
needle_len = len(needle)
if (needle_len > haystack_len) or (not haystack_len) or (not needle_len):
return -1
prefix_table = get_prefix_table(needle)
m = i = 0
while((i<needle_len) and (m<haystack_len)):
if haystack[m] == needle[i]:
i += 1
m += 1
else:
if i != 0:
i = prefix_table[i-1]
else:
m += 1
if i==needle_len and haystack[m-1] == needle[i-1]:
return m - needle_len
else:
return -1
if __name__ == '__main__':
needle = 'abcaby'
haystack = 'abxabcabcaby'
print strstr(haystack, needle)