C++實現兩個字串之間的Levenshtein Distance(編輯距離)
阿新 • • 發佈:2019-02-07
1.什麼是Levenshtein Distance
Levenshtein Distance,又稱編輯距離,指的是兩個字串之間,由一個轉換成另一個所需的最少編輯操作次數。許可的編輯操作包括將一個字元替換成另一個字元,插入一個字元,刪除一個字元。levenshtein() 函式返回兩個字串之間的 Levenshtein 距離。編輯距離的演算法是首先由俄國科學家Levenshtein提出的,故又叫Levenshtein Distance。
2.演算法
步驟 | 說明 |
---|---|
1 |
設定n為字串s的長度。("GUMBO") 設定m為字串t的長度。("GAMBOL") 如果n等於0,返回m並退出。 如果m等於0,返回n並退出。 構造兩個向量v0[m+1] 和v1[m+1],串聯0..m之間所有的元素。 |
2 | 初始化 v0 to 0..m。 |
3 | 檢查 s (i from 1 to n) 中的每個字元。 |
4 | 檢查 t (j from 1 to m) 中的每個字元 |
5 |
如果 s[i] 等於 t[j],則編輯代價為 0; 如果 s[i] 不等於 t[j],則編輯代價為1。 |
6 |
設定單元v1[j]為下面的最小值之一: a、緊鄰該單元上方+1:v1[j-1] + 1 b、緊鄰該單元左側+1:v0[j] + 1 c、該單元對角線上方和左側+cost:v0[j-1] + cost |
7 | 在完成迭代 (3, 4, 5, 6) 之後,v1[m]便是編輯距離的值。 |
其中,cost為編輯代價,當字元相等時,為0,否則為1.
下面將演示如何計算"GUMBO"和"GAMBOL"兩個字串的Levenshtein距離
步驟1、2
v0 | v1 | ||||
G | U | M | B | O | |
0 | 1 | 2 | 3 | 4 | 5 |
G | 1 | ||||
A | 2 | ||||
M | 3 | ||||
B | 4 | ||||
O | 5 | ||||
L | 6 |
步驟3-6,當 i = 1
v0 | v1 | ||||
G | U | M | B | O | |
0 | 1 | 2 | 3 | 4 | 5 |
G | 1 | 0 | |||
A | 2 | 1 | |||
M | 3 | 2 | |||
B | 4 | 3 | |||
O | 5 | 4 | |||
L |
6 |
5 |
步驟3-6,當 i = 2
v0 | v1 | ||||
G | U | M | B | O | |
0 | 1 | 2 | 3 | 4 | 5 |
G | 1 | 0 | 1 | ||
A | 2 | 1 | 1 | ||
M | 3 | 2 | 2 | ||
B | 4 | 3 | 3 | ||
O | 5 | 4 | 4 | ||
L | 6 | 5 | 5 |
步驟3-6,當 i = 3
v0 | v1 | ||||
G | U | M | B | O | |
0 | 1 | 2 | 3 | 4 | 5 |
G | 1 | 0 | 1 | 2 | |
A | 2 | 1 | 1 | 2 | |
M | 3 | 2 | 2 | 1 | |
B | 4 | 3 | 3 | 2 | |
O | 5 | 4 | 4 | 3 | |
L | 6 | 5 | 5 | 4 |
步驟3-6,當 i = 4
v0 | v1 | ||||
G | U | M | B | O | |
0 | 1 | 2 | 3 | 4 | 5 |
G | 1 | 0 | 1 | 2 | 3 |
A | 2 | 1 | 1 | 2 | 3 |
M | 3 | 2 | 2 | 1 | 2 |
B | 4 | 3 | 3 | 2 | 1 |
O | 5 | 4 | 4 | 3 | 2 |
L | 6 | 5 | 5 | 4 | 3 |
步驟3-6,當 i = 5
v0 | v1 | |||||
G | U | M | B | O | ||
0 | 1 | 2 | 3 | 4 | 5 | |
G | 1 | 0 | 1 | 2 | 3 | 4 |
A | 2 | 1 | 1 | 2 | 3 | 4 |
M | 3 | 2 | 2 | 1 | 2 | 3 |
B | 4 | 3 | 3 | 2 | 1 | 2 |
O | 5 | 4 | 4 | 3 | 2 | 1 |
L | 6 | 5 | 5 | 4 | 3 |
2 |
步驟7
編輯距離就是矩陣右下角的值,v1[m] == 2。
3.程式碼實現
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
#define min(a,b) ((a<b)?a:b)
//演算法
int ldistance(const string source, const string target)
{
//step 1
int n = source.length();
int m = target.length();
if (m == 0) return n;
if (n == 0) return m;
//Construct a matrix
typedef vector< vector<int> > Tmatrix;
Tmatrix matrix(n + 1);
for (int i = 0; i <= n; i++) matrix[i].resize(m + 1);
//step 2 Initialize
for (int i = 1; i <= n; i++) matrix[i][0] = i;
for (int i = 1; i <= m; i++) matrix[0][i] = i;
//step 3
for (int i = 1; i <= n; i++)
{
const char si = source[i - 1];
//step 4
for (int j = 1; j <= m; j++)
{
const char dj = target[j - 1];
//step 5
int cost;
if (si == dj){
cost = 0;
}
else{
cost = 1;
}
//step 6
const int above = matrix[i - 1][j] + 1;
const int left = matrix[i][j - 1] + 1;
const int diag = matrix[i - 1][j - 1] + cost;
matrix[i][j] = min(above, min(left, diag));
}
}//step7
return matrix[n][m];
}
void main(){
string s;
s = "ABC";
string d;
d = "abcd";
//cout << "source=";
//cin >> s;
//cout << "diag=";
//cin >> d;
int dist = ldistance(s, d);
cout << "dist=" << dist << endl;
system("pause");
}
參考資源: