python字串以及他的匹配演算法
阿新 • • 發佈:2018-11-10
對於python字串的實現來說,它本身是一個線性表,根據前面我們講過的關於線性表的主體,我們可以實現一個字串物件,在這裡我們需要說明的是,python字串是一個不可變的物件,而且它的實現是一個一體式的順序表的實現(概念見前面文章)
所以,對於一個字串的物件,它除了有字元儲存空間外還有字串長度和一些配置資訊的空間。(注意一點:python沒有字元物件,單個字元也認為是一個字串物件)
所以對於字串的長度len函式和按下標取值複雜度都是O(1),但是其他的操作,如字串的複製,切片等,都是O(n)。
再講一下字串的複製(切片)的過程,這些過程都會建立一個新的字串,python首先會計算出所需要儲存空間的大小,然後一個個的計算出要儲存再空間裡的字串。這是python字串複製(切片)的一個過程。
對於字串中子串的查詢,是一個高深的問題,當前的演算法實現中經典的有兩種,一種是樸素匹配演算法,一種是無回溯的KMP演算法。
接下來我們將樸素的匹配演算法。
過程是:
目標字串t, 模式字串p。
將p中的字元依次跟t中的比較,如果有一個不匹配,將t字元移到下一位, 再講p中的字元一個個的匹配,知道返回t中與p匹配的字串。
這裡有兩種實現方法,一種返回第一個匹配的子串,另一種返回左右匹配子串的首字元的位置。實現如下:
#第一種 def naive_matching(t, p): # 這種找出第一個子串匹配的位置 m, n = len(p), len(t) i, j = 0, 0 while i < m and j < n: if p[i] == t[j]: i, j = i + 1, j + 1 else: i, j = 0, j-i+1 if i == m: return j -i return -1 print(naive_matching('fwekfwe', 'we')) >>> 1
第二種
def naive_matching(t, p): list = [] # 用於儲存匹配子串的首字元位置 for i in range(len(t)): x, z, times = i, 0, len(p) if p[z] == t[i]: while times > 1: z += 1 x += 1 if p[z] != t[x]: break times -= 1 else: # 當while/for迴圈正常退出時才會執行相應的else語句塊 list.append(i) return list # 這種匹配可以找出所有匹配子串的位置 print(naive_matching('rewwwtrtwewrfrwe', 'ww')) >>> [2, 3]
這兩種實現方法的複雜度相對而言都比較高(有回溯),下一篇我們會將什麼是回溯和無回溯的KMP演算法。