首先是next陣列的獲取,用了乙個遞迴的方法,時間複雜度為o(m),m為模式串的長度
def
getnext
(p):
n = len(p)
next = [-1] * n
k = -1
j = 0
while(j < n - 1):
if k == -1
or p[k] == p[j]:
k += 1
j += 1
next[j] = k
else:
k = next[k]
return next
next陣列改進,即實現nextval陣列
def
getnextval
(p):
n = len(p)
next = [-1] * n
k = -1
j = 0
while j < n-1:
if k == -1
or p[j] == p[k]:
k += 1
j += 1
#//p[k]表示字首,p[j]表示字尾
if p[j] != p[k]:
next[j] = k
else:
# 因為不能出現p[j] = p[next[j]],所以當出現時需要繼續遞迴,k = next[k] = next[next[k]]
next[j] = next[k]
else:
k = next[k]
return next
kmp實現,複雜度為o(n),n為文字字串的長度
def
kmpsearch
(s, p):
next = getnext(p)
slength = len(s)
plength = len(p)
i = 0
j = 0
while(i < slength and j < plength):
if j == -1
or s[i] == p[j]:
i += 1
j += 1
else:
j = next[j]
if j == plength:
return i - j #返回文字的索引
else:
return -1
#沒有找到匹配的字串
測試
s = 'bbc abcdab abcdabcdabde'
p = 'abcdabc'
print("next = ", getnext(p))
print("result = ",kmpsearch(s, p))
結果
next = [-1, 0, 0, 0, 0, 1, 2]
result = 11 #index
整個方法的複雜度為o(m+n)
參考
字串查詢演算法kmp
字串查詢最簡單的方法就是乙個乙個地 滑動 查詢。這樣查詢演算法複雜度可定很高,假設pattern的長度為m,文字txt的長度為n,那麼演算法複雜度為o m n m 1 kmp模式搜尋演算法 kmp knuth morris pratt 我只認識knuth,大名鼎鼎的高納德老頭子嘛。kmp演算法的基本...
字串查詢演算法kmp
給定乙個文字串s,和乙個匹配串p,要求查詢p第一次在s中出現的位置。常見的方法如暴力搜素,逐個匹配s i p j 若匹配,下標後移。不匹配,i回溯到這次匹配前的下一位置,j置為0,重新匹配。最壞情況,時間複雜度o n m int violencesearch char s,char p else i...
字串查詢KMP演算法
如果你用過ctrl f這個快捷鍵,那麼你有很大的概率使用過這個演算法,這就是在待查詢字串 可能有成千上萬個字元 中找出模式串 比較小,可能有幾個字元 可能找到大於或者等於1次的位置。例如,在ababcd中找出abc。這裡介紹演算法思想,只給出了第一次出現的位置。void find char t,ch...