標籤:
首先我們看一下簡單的字串匹配.
你可以把文本字串s固定,模式字串p從s對齊的左邊緣,作為承擔部分完全一致,匹配成功,失敗將是模式字串p整體向右1地點,繼續檢查對齊部分,重複.
#樸素匹配def naive_match(s, p): m = len(s); n = len(p) for i in range(m-n+1):#起始指標i if s[i:i+n] == p: return True return False
關於kmp演算法,講的最好的當屬阮一峰的<字串匹配的KMP演算法>.一路讀下來,豁然開朗.
事實上就是,
對模式串p進行預先處理,得到前尾碼的部分匹配表,使得我們能夠藉助已知資訊,算出能夠右移多少位.即 kmp = 樸素匹配 + 移動多位.
很多其它細節請看阮一峰的文章,這裡就不展開了.
以下給出python的代碼實現.
#KMPdef kmp_match(s, p): m = len(s); n = len(p) cur = 0#起始指標cur table = partial_table(p) while cur<=m-n: for i in range(n): if s[i+cur]!=p[i]: cur += max(i - table[i-1], 1)#有了部分匹配表,我們不僅僅是單純的1位1位往右移,能夠一次移動多位 break else: return True return False#部分匹配表def partial_table(p): '''partial_table("ABCDABD") -> [0, 0, 0, 0, 1, 2, 0]''' prefix = set() postfix = set() ret = [0] for i in range(1,len(p)): prefix.add(p[:i]) postfix = {p[j:i+1] for j in range(1,i+1)} ret.append(len((prefix&postfix or {''}).pop())) return retprint naive_match("BBC ABCDAB ABCDABCDABDE", "ABCDABD")print partial_table("ABCDABD")print kmp_match("BBC ABCDAB ABCDABCDABDE", "ABCDABD")
著作權聲明:本文部落格原創文章,部落格,未經同意,不得轉載。
流動python - 字串KMP匹配