最小編輯距離定義
將一個字符串變成另外一個字符串所用的最少操作數,每次只能增加、刪除或者替換一個字符。
例1: 輸入: word1 = "horse", word2 = "ros"
輸出: 3
解釋:
horse -> rorse (replace 'h' with 'r')
rorse -> rose (remove 'r')
rose -> ros (remove 'e')
例2:
輸入: word1 = "intention", word2 = "execution"
輸出: 5
解釋:
intention -> inention (remove 't')
inention -> enention (replace 'i' with 'e')
enention -> exention (replace 'n' with 'x')
exention -> exection (replace 'n' with 'c')
exection -> execution (insert 'u')
例子引出算法
我們有兩個詞彙,word1爲michaelab , word2 爲 michaelxy。 (這裏我們爲了比較容易理解,使用word1和word2的長度假定相等。) dp [i] [j] 作爲word1轉換爲word2的最小編輯距離, 我們就是要計算這個矩陣。
顯然如果b==y, 那麼dis[i][j] = dis[i-1][j-1] 也就是從後面看起,如果兩個字符串的最後一個字符相同,那我們就看dis[i-1][j-1]。
假設word1[i]和word2[j](此處i = j)分別爲:michaelab和michaelxy 我們規定三種操作:添加,刪除,替換
如果b!=y,那麼:
添加:也就是在michaelab後面添加一個y,那麼word1就變成了michaelaby,此時
dis[i][j] = 1 + dis[i][j-1];
上式中,1代表剛剛的添加操作,添加操作後,word1變成michaelaby,word2爲michaelxy。dis[i][j-1]代表從word[i]轉換成word[j-1]的最小Edit Distance,也就是michaelab轉換成michaelx的最小Edit Distance,由於兩個字符串尾部的y==y,所以只需要將michaelab變成michaelx就可以了,而他們之間的最小Edit Distance就是dis[i][j-1]。
刪除:也就是將michaelab後面的b刪除,那麼word1就變成了michaela,此時
dis[i][j] = 1 + dis[i-1][j];
上式中,1代表剛剛的刪除操作,刪除操作後,word1變成michaela,word2爲michaelxy。dis[i-1][j]代表從word[i-1]轉換成word[j]的最小Edit Distance,也就是michaela轉換成michaelxy的最小Edit Distance,所以只需要將michaela變成michaelxy就可以了,而他們之間的最小Edit Distance就是dis[i-1][j]。
替換:也就是將michaelab後面的b替換成y,那麼word1就變成了michaelay,此時
dis[i][j] = 1 + dis[i-1][j-1];
上式中,1代表剛剛的替換操作,替換操作後,word1變成michaelay,word2爲michaelxy。dis[i-1][j-1]代表從word[i-1]轉換成word[j-1]的最小Edit Distance,也即是michaelay轉換成michaelxy的最小Edit Distance,由於兩個字符串尾部的y==y,所以只需要將michaela變成michaelx就可以了,而他們之間的最小Edit Distance就是dis[i-1][j-1]。
python代碼實現
def minDist(word1, word2):
len1 = len(word1)
len2 = len(word2)
dp = [[0 for i in range(len1+1)] for j in range(len2+1)]
print(dp) # 構造dp矩陣
i = 0
for item in dp:
item[0] = i
i += 1
i = 0
for i in range(len1+1):
dp[0][i] = i
i += 1
for i in range(1, len1+1):
for j in range(1, len2+1):
if word1[i-1] == word2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
insert = 1 + dp[i][j-1]
delete = 1 + dp[i-1][j]
replace = dp[i-1][j-1] + 1
dp[i][j] = min(insert, delete, replace)
return dp
if __name__ == '__main__':
word1 = 'daaqerdwq'
word2 = 'aswdreqew'
dp = minDist(word1, word2)
for i in dp:
print(i)
輸出結果:
可以看出 最右下角元素爲2 所以最小編輯距離爲2
圖太難畫了,,我真的不想畫