編輯距離演算法詳解:Levenshtein Distance演算法
轉自:
編輯距離,又稱Levenshtein距離(也叫做Edit Distance),是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。
演算法基本原理:假設我們可以使用d[ i , j ]個步驟(可以使用一個二維陣列儲存這個值),表示將串s[ 1…i ] 轉換為 串t [ 1…j ]所需要的最少步驟個數,那麼,在最基本的情況下,即在i等於0時,也就是說串s為空,那麼對應的d[0,j] 就是 增加j個字元,使得s轉化為t,在j等於0時,也就是說串t為空,那麼對應的d[i,0] 就是 減少 i個字元,使得s轉化為t。
然後我們考慮一般情況,加一點動態規劃的想法,我們要想得到將s[1..i]經過最少次數的增加,刪除,或者替換操作就轉變為t[1..j],那麼我們就必須在之前可以以最少次數的增加,刪除,或者替換操作,使得現在串s和串t只需要再做一次操作或者不做就可以完成s[1..i]到t[1..j]的轉換。所謂的“之前”分為下面三種情況:
1)我們可以在k個操作內將 s[1…i] 轉換為 t[1…j-1]
2)我們可以在k個操作裡面將s[1..i-1]轉換為t[1..j]
3)我們可以在k個步驟裡面將 s[1…i-1] 轉換為 t [1…j-1]
針對第1種情況,我們只需要在最後將 t[j] 加上
針對第2種情況,我們只需要在最後將s[i]移除,然後再做這k個操作,所以總共需要k+1個操作。
針對第3種情況,我們只需要在最後將s[i]替換為 t[j],使得滿足s[1..i] == t[1..j],這樣總共也需要k+1個操作。而如果在第3種情況下,s[i]剛好等於t[j],那我們就可以僅僅使用k個操作就完成這個過程。
最後,為了保證得到的操作次數總是最少的,我們可以從上面三種情況中選擇消耗最少的一種最為將s[1..i]轉換為t[1..j]所需要的最小操作次數。
演算法基本步驟:
(1)構造 行數為m+1 列數為 n+1 的矩陣 , 用來儲存完成某個轉換需要執行的操作的次數,將串s[1..n] 轉換到 串t[1…m] 所需要執行的操作次數為matrix[n][m]的值;
(2)初始化matrix第一行為0到n,第一列為0到m。
Matrix[0][j]表示第1行第j-1列的值,這個值表示將串s[1…0]轉換為t[1..j]所需要執行的操作的次數,很顯然將一個空串轉換為一個長度為j的串,只需要j次的add操作,所以matrix[0][j]的值應該是j,其他值以此類推。
(3)檢查每個從1到n的s[i]字元;
(4)檢查每個從1到m的s[i]字元;
(5)將串s和串t的每一個字元進行兩兩比較,如果相等,則讓cost為0,如果不等,則讓cost為1(這個cost後面會用到);
(6)a、如果我們可以在k個操作裡面將s[1..i-1]轉換為t[1..j],那麼我們就可以將s[i]移除,然後再做這k個操作,所以總共需要k+1個操作。
b、如果我們可以在k個操作內將 s[1…i] 轉換為 t[1…j-1] ,也就是說d[i,j-1]=k,那麼我們就可以將 t[j] 加上s[1..i],這樣總共就需要k+1個操作。
c、如果我們可以在k個步驟裡面將 s[1…i-1] 轉換為 t [1…j-1],那麼我們就可以將s[i]轉換為 t[j],使得滿足s[1..i] == t[1..j],這樣總共也需要k+1個操作。(這裡加上cost,是因為如果s[i]剛好等於t[j],那麼就不需要再做替換操作,即可滿足,如果不等,則需要再做一次替換操作,那麼就需要k+1次操作)
因為我們要取得最小操作的個數,所以我們最後還需要將這三種情況的操作個數進行比較,取最小值作為d[i,j]的值;
d、然後重複執行3,4,5,6,最後的結果就在d[n,m]中;