一,演算法介紹
在cs124課程的第一周提到 求解兩個字串相似度的演算法---minimum edit distance(最短編輯距離)演算法。該演算法在nlp(自然語言處理)中也會用到。
如何定義相似度呢?任給兩個字串x 和y,使用以下三種操作將 字串x 變到 字串y :①插入(insert)操作;②刪除操作(delete);③替換操作(substitute)
比如 字串x="intention" , 字串y="execution"。從字串x 轉換成 字串y 如下圖所示:
定義:插入操作的代價為1,刪除操作的代價為1,替換操作的代價為2(稱為: levenshtein distance)。那麼,"intention" 變成 "execution" 執行了三次替換,一次刪除,一次插入。因此,總代價為8
而這個代價又稱為編輯距離, 用之來 衡量 兩個字串的相似程度。顯然,若兩個字串越相似,則從乙個字串變到另乙個字串所需要的 「操作」 步驟 就越少。
二,動態規則求解最短編輯距離
為什麼能用動態規劃來求解呢?ⓐ該問題可以分解成若干個子問題;ⓑ子問題之間具有重疊性(可「查表」),具體可參考一些動態規劃的示例1,示例2.
假設字串x的長度為n,字串y的長度為m,用d[n][m] 表示 字串x 轉換成 字串y 的最短編輯距離
要想從 長度為 i 的源字串x 轉換成 長度為 j 的目標字串y,有三種方式:
①先將 源字串x 的前 i-1 個字元 x[1...i-1] 轉換成 目標字串y[1...j], 然後再 刪除字串x 的第 i 個字元source[i]
②先將 源字串x[1...j] 轉換成 目標字串y[1...j-1] ,然後再 插入字串y的第 j 個字元 target[j]
③先將 源字串x[1...i-1] 轉換成 目標字串y[1...j-1],然後 源字串中的 第 i 個字元x[i] 替換為 目標字串的第 j 個字元 y[j]
為什麼 只有上述三種方式呢?
因為我們是將 源問題 的求解,分解成若干個子問題的求解,子問題的規模比原問題要小1。源問題 x[1...i] 轉換成 y[1...j] 。比如,子問題是:先將x[1...i-1] 轉換成 y[1...j] ,...
結合前面定義的 操作代價(刪除和插入操作代價為1,替換操作為2),就是下面這個公式:
解釋一下為什麼 if source[i]=target[j]時,替換的 代價為0呢?if source[i]=target[j] 表明 字串x 的第 i 個字串 和 字串y的第 j 個字元是相同的
要想將 x[1...i] 轉換成 y[1...j] ,對於第三種轉換方式:先將 源字串x[1...i-1] 轉換成 目標字串y[1...j-1] ,既然:字串x 的第 i 個字串 和 字串y的第 j 個字元是相同的,那就相當於「自己替換自己」,或者說是 不需要替換操作了嘛。這也是下面**實現邏輯:
if (source.charat(i-1) == target.charat(j-1)) 10
11 public intsimilardegree(string source, string target) else38 }39 }40 returndp[sourcelen][targetlen];41 }42
43 private int min(int insert, int delete, intsubstitute) 48 }
參考:stanford cs124課程
原文:
最短編輯距離
給定兩個字串a和b,現在要將a經過若干操作變為b,可進行的操作有 刪除 將字串a中的某個字元刪除。插入 在字串a的某個位置插入某個字元。替換 將字串a中的某個字元替換為另乙個字元。現在請你求出,將a變為b至少需要進行多少次操作。輸入格式 第一行包含整數n,表示字串a的長度。第二行包含乙個長度為n的字...
最短編輯距離
題目鏈結 給定兩個字串a和b,現在要將a經過若干操作變為b,可進行的操作有 刪除 將字串a中的某個字元刪除。插入 在字串a的某個位置插入某個字元。替換 將字串a中的某個字元替換為另乙個字元。現在請你求出,將a變為b至少需要進行多少次操作。輸入格式 第一行包含整數n,表示字串a的長度。第二行包含乙個長...
最短編輯距離
題目 給定兩個字串 a 和 b,現在要將 a 經過若干操作變為 b,可進行的操作有 刪除 將字串 a 中的某個字元刪除。插入 在字串 a 的某個位置插入某個字元。替換 將字串 a 中的某個字元替換為另乙個字元。現在請你求出,將 a 變為 b 至少需要進行多少次操作。集合 將a 1i 變成b 1j 的...