KMP演算法,字串 序列匹配位置的查詢

2021-08-19 00:00:08 字數 3396 閱讀 1669

kmp演算法是乙個設計精巧的匹配查詢演算法,用於查詢2個字串或者序列,乙個(小的)在另乙個(大的)中最佳匹配位置。演算法的核心思想是跳過一些已經確定不會匹配的部分。

python實現如下:

#:kmp字串匹配演算法

defkmp

(bigstr:str, smallstr:str, all = false)->(list,bool, int):

''' kmp演算法,用於查詢後字串在前面字串的匹配位置。

:param bigstr: 包含的字串

:param smallstr: 要檢測是否含有的字串

:param all: 是否要找到所有的位置。預設為false

:return: 匹配(或最佳匹配)的位置的列表,從0開始,-1為完全沒有找到。

bool變數是否是精確匹配。最後第三個返回值是匹配的長度。

'''defcal_next

(string:str)->np.ndarray:

''' kmp演算法所需要的子函式

:param string:

:return:

'''k = -1

length = len(string)

nextarr = -np.ones(length,dtype=int) #全賦值為-1,不過演算法裡只要賦值為-1即可

for qq in range(1,length):

while string[k + 1] != string[qq] and k>-1: # 第乙個放過

k = nextarr[k] # 向前回溯。qq一定大於k,故安全

if string[k+1] == string[qq]:

k += 1

nextarr[qq] = k

return nextarr

nexta = cal_next(smallstr)

kk = -1

exact = false

bestpos = list()

bestk = -1

# store the answer

biglen = len(bigstr)

smalen = len(smallstr)

for ii in range(0,biglen):

while bigstr[ii] != smallstr[kk+1] and kk>-1:

kk = nexta[kk]

if bigstr[ii] == smallstr[kk+1]:

kk += 1

if kk > bestk:

bestk = kk

bestpos = [ii-kk,]

elif kk == bestk:

else:

pass

if kk == smalen - 1:

exact = true

ifnot all: #只要乙個就好的話

# return ii - kk, exact

return bestpos, exact, bestk+1

else:

kk = -1

# 找到了乙個完全匹配,繼續開始

return bestpos, exact, bestk+1

defkmp_int_near

(bigstr: str, smallstr: str, all=false, near=0) -> (list, bool, int):

''' kmp演算法另一修改版,用於查詢後字串在前面字串的匹配位置。

這裡計算的可以不是字串,只要是可迭代序列即可(支援操作)。但要求是數值變數(支援+->=《操作)。

判定某兩個字元/元素相等的比較是近似比較,相互差值在near範圍內即認為是相等。near預設值是0。

:param bigstr: 包含的字串

:param smallstr: 要檢測是否含有的字串

:param all: 是否要找到所有的位置。預設為false

:param near: 認為相等的範圍域,預設是0。

:return: 匹配(或最佳匹配)的位置的列表,從0開始,-1為完全沒有找到。

bool變數是否是精確匹配。最後第三個返回值是匹配長度。

'''nearequa = lambda a, b: a < b + near and a > b - near

#~ 相等比較函式

defcal_next

(string: str) -> np.ndarray:

k = -1

length = len(string)

nextarr = -np.ones(length, dtype=int) # 全賦值為-1,不過演算法裡只要賦值為-1即可

for qq in range(1, length):

while

not nearequa(string[k + 1], string[qq]) and k > -1: # 第乙個放過

k = nextarr[k] # 向前回溯。qq一定大於k,故安全

if nearequa(string[k + 1], string[qq]):

k += 1

nextarr[qq] = k

return nextarr

nexta = cal_next(smallstr)

kk = -1

exact = false

bestpos = list()

bestk = -1

# store the answer

biglen = len(bigstr)

smalen = len(smallstr)

for ii in range(0, biglen):

while

not nearequa(bigstr[ii], smallstr[kk + 1]) and kk > -1:

kk = nexta[kk]

if nearequa(bigstr[ii], smallstr[kk + 1]):

kk += 1

if kk > bestk:

bestk = kk

bestpos = [ii - kk, ]

elif kk == bestk:

else:

pass

if kk == smalen - 1:

exact = true

ifnot all: # 只要乙個就好的話

# return ii - kk, exact

return bestpos, exact, bestk + 1

else:

kk = -1

# 找到了乙個完全匹配,繼續開始

return bestpos, exact, bestk + 1

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的第乙個字元,依次比較下去,直到得出最後的匹配...