【NLP】最小編輯距離

編輯距離

編輯距離又稱Levenshtein距離,是指將一個字符串轉爲另一個字符串所需的字符編輯次數,包括以下三種操作:

  • 插入 - 在任意位置插入一個字符
  • 刪除 - 將任意一個字符刪除
  • 替換 - 將任意一個字符替換爲另一個字符

最小編輯距離是指將一個字符串轉爲另一個字符串所需的最少字符編輯次數。

思路

計算最小編輯距離需要用到動態規劃。對於兩個字符串AABB,設f(i,j)f(i, j)表示將AA的前ii個字符構成的子串轉爲BB的前jj個字符構成的子串所需的最少次數,那麼f(i,0)=if(i, 0) = if(0,j)=jf(0, j) = j,從AABB的最小編輯距離即f(m,n)f(m, n)mmnn分別爲AABB的長度。
由於f(i,0)f(i, 0)f(0,j)f(0, j)已確定,可以考慮從f(i,j)f(i, j)遞推到f(i+1,j)f(i+1, j)f(i,j+1)f(i, j+1)f(i+1,j+1)f(i+1, j+1),或者反過來,考慮從f(i1,j)f(i-1, j)f(i,j1)f(i, j-1)f(i1,j1)f(i-1, j-1)遞推到f(i,j)f(i, j)。顯然,前兩種情況只需要在最後插入一個字符,即f(i,j)=f(i1,j)+1f(i, j) = f(i-1, j)+1f(i,j)=f(i,j1)+1f(i, j) = f(i, j-1)+1。而最後一種情況需要比較AA的第ii個字符和BB的第jj個字符,若相等,則f(i,j)=f(i1,j1)f(i, j) = f(i-1, j-1);否則需要進行替換操作,即f(i,j)=f(i1,j1)+1f(i, j) = f(i-1, j-1)+1。因此f(i,j)f(i, j)取三者最小值,遞推公式爲
f(i,j)=min{(f(i1,j)+1f(i,j1)+1f(i1,j1)+{0,A[i]=B[j]1,otherwise f(i,j) = min \begin{cases} (f(i-1, j)+1 \\ f(i, j-1)+1 \\ f(i-1, j-1)+ \begin{cases} 0, A[i] = B[j] \\ 1, otherwise \end{cases} \end{cases}

複雜度

時間複雜度和空間複雜度均爲O(mn)O(mn),其中mmnn分別爲AABB的長度。

Python代碼

完整代碼見Github

def Levenshtein(str1, str2):
  m = len(str1) + 1
  n = len(str2) + 1

  dp = [[0 for _ in range(n)] for _ in range(m)]
  for i in range(m):
    dp[i][0] = i
  for j in range(n):
    dp[0][j] = j

  for i in range(1, m):
    for j in range(1, n):
      if (str1[i-1] == str2[j-1]):
        dp[i][j] = dp[i-1][j-1]
      else:
        dp[i][j] = 1 + min(dp[i-1][j-1], dp[i-1][j], dp[i][j-1])
  
  return dp[m-1][n-1]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章