編輯距離及編輯距離演算法
編輯距離概念描述:
編輯距離,又稱Levenshtein距離,是指兩個字串之間,由一個轉成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。
例如將kitten一字轉成sitting:
- sitten (k→s)
- sittin (e→i)
- sitting (→g)
俄羅斯科學家Vladimir Levenshtein在1965年提出這個概念。
問題:找出字串的編輯距離,即把一個字串s1最少經過多少步操作變成程式設計字串s2,操作有三種,新增一個字元,刪除一個字元,修改一個字元
解析:
首先定義這樣一個函式——edit(i, j),它表示第一個字串的長度為i的子串到第二個字串的長度為j的子串的編輯距離。
顯然可以有如下動態規劃公式:
- if i == 0 且 j == 0,edit(i, j) = 0
- if i == 0 且 j > 0,edit(i, j) = j
- if i > 0 且j == 0,edit(i, j) = i
- if i ≥ 1 且 j ≥ 1 ,edit(i, j) == min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) },當第一個字串的第i個字元不等於第二個字串的第j個字元時,f(i, j) = 1;否則,f(i, j) = 0。
0 | f | a | i | l | i | n | g | |
0 | ||||||||
s | ||||||||
a | ||||||||
i | ||||||||
l | ||||||||
n |
0 | f | a | i | l | i | n | g | |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
s | 1 | |||||||
a | 2 | |||||||
i | 3 | |||||||
l | 4 | |||||||
n | 5 |
計算edit(1, 1),edit(0, 1) + 1 == 2,edit(1, 0) + 1 == 2,edit(0, 0) + f(1, 1) == 0 + 1 == 1,min(edit(0, 1),edit(1, 0),edit(0, 0) + f(1, 1))==1,因此edit(1, 1) == 1。 依次類推:
0 | f | a | i | l | i | n | g | |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
s | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
a | 2 | 2 | ||||||
i | 3 | |||||||
l | 4 | |||||||
n | 5 |
edit(2, 1) + 1 == 3,edit(1, 2) + 1 == 3,edit(1, 1) + f(2, 2) == 1 + 0 == 1,其中s1[2] == 'a' 而 s2[1] == 'f'‘,兩者不相同,所以交換相鄰字元的操作不計入比較最小數中計算。以此計算,得出最後矩陣為:
0 | f | a | i | l | i | n | g | |
0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
s | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
a | 2 | 2 | 1 | 2 | 3 | 4 | 5 | 6 |
i | 3 | 3 | 2 | 1 | 2 | 3 | 4 | 5 |
l | 4 | 4 | 3 | 2 | 1 | 2 | 3 | 4 |
n | 5 | 5 | 4 | 3 | 2 | 2 | 2 | 3 |
程式(C++):注意二維陣列動態分配和釋放的方法!!
#include <iostream> #include <string> using namespace std; int min(int a, int b) { return a < b ? a : b; } int edit(string str1, string str2) { int max1 = str1.size(); int max2 = str2.size(); int **ptr = new int*[max1 + 1]; for(int i = 0; i < max1 + 1 ;i++) { ptr[i] = new int[max2 + 1]; } for(int i = 0 ;i < max1 + 1 ;i++) { ptr[i][0] = i; } for(int i = 0 ;i < max2 + 1;i++) { ptr[0][i] = i; } for(int i = 1 ;i < max1 + 1 ;i++) { for(int j = 1 ;j< max2 + 1; j++) { int d; int temp = min(ptr[i-1][j] + 1, ptr[i][j-1] + 1); if(str1[i-1] == str2[j-1]) { d = 0 ; } else { d = 1 ; } ptr[i][j] = min(temp, ptr[i-1][j-1] + d); } } cout << "**************************" << endl; for(int i = 0 ;i < max1 + 1 ;i++) { for(int j = 0; j< max2 + 1; j++) { cout << ptr[i][j] << " " ; } cout << endl; } cout << "**************************" << endl; int dis = ptr[max1][max2]; for(int i = 0; i < max1 + 1; i++) { delete[] ptr[i]; ptr[i] = NULL; } delete[] ptr; ptr = NULL; return dis; } int main(void) { string str1 = "sailn"; string str2 = "failing"; int r = edit(str1, str2); cout << "the dis is : " << r << endl; return 0; }
執行效果:
轉載來自:http://www.cnblogs.com/biyeymyhjob/archive/2012/09/28/2707343.html
相關文章
- 編輯距離演算法演算法
- 【DP】編輯距離
- LeetCode72編輯距離LeetCode
- 線性dp:編輯距離
- 902.最短編輯距離
- 動態規劃-編輯距離動態規劃
- Java LeetCode 72. 編輯距離JavaLeetCode
- Leetcode 編輯距離(動態規劃)LeetCode動態規劃
- Levenshtein:計算字串的編輯距離字串
- 面試程式碼題(華為)編輯距離面試
- 【leetcode】72. Edit Distance 編輯距離計算LeetCode
- 資料對齊-編輯距離演算法詳解(Levenshtein distance)演算法
- 演算法:編輯距離問題(動態規劃,詳細解答)演算法動態規劃
- 單詞拼寫糾正-05-2452.力扣 距離字典兩次編輯距離以內的單詞力扣
- 怎樣衡量兩個字串的相似度(編輯距離動態規劃求解)字串動態規劃
- 馬氏距離與歐氏距離
- 單詞拼寫糾正-04-161.力扣 相隔為 1 的編輯距離力扣
- 【Python】距離Python
- JavaScript 元素距離視窗頂部的距離JavaScript
- 曼哈頓距離與切比雪夫距離
- JavaScript獲取元素距離文件頂部的距離JavaScript
- 最小距離分類器,互動式選取影像樣本分類資料,進行最小距離分類(實現歐式距離,馬氏距離,計程距離)
- Laravel 距離排序Laravel排序
- unit原子距離
- 餘弦距離
- 馬氏距離
- Hetao P2071 打字遊戲 題解 [ 綠 ] [ 最小生成樹 ] [ 動態規劃 ] [ 編輯距離 ]遊戲動態規劃
- 距離度量學習
- 曼哈頓距離與切比雪夫距離的互化
- milvus 使用 l2 歐式距離計算向量的距離,計算出來的距離的最大值是多少?
- 距離容差來源
- 461. 漢明距離
- 漢明距離(Hamming distance)
- vscode開啟關閉編輯區域頂部固定區域 頂部有一段行數距離高度 StickyScrollVSCode
- Markdown線上、離線編輯器與使用教程
- LeetCode 461. 漢明距離LeetCode
- LeetCode 834 樹中距離之和LeetCode
- 經緯度距離換算