編輯距離演算法,是自然語言處理中的重要的演算法之一。也是從多個相似的字串組中提取字串的有利的**。編輯距離演算法,也稱為ld演算法。ld演算法就是自然語言處理(nlp)裡的「編輯距離」演算法。**科學家levenshtein提出的,故又叫levenshtein distance (ld演算法)
【定義】設a和b是兩個字串。將字串a轉換為字串b所用的最少字元運算元稱為字串a到字串b的編輯距離。( 這裡所說的字元操作包括:刪除乙個字元,插入乙個字元,修改乙個字元)
這個演算法的原理,我其實並不清楚,但我知道如何利用矩陣來計算兩個字串的距離。舉例說明如何用ld演算法來解決實現工作中的問題。現以 計算ggatcga 和gaattcagtta的距離為例來說明。
ggatcga 和gaattcagtta在結構上非常的相似,我們肉眼觀察到,通過下面的變換,可以讓乙個字串變成另外乙個字串,其中,「-」表示新增。
gga-tc-g- -a
gaattcagtta
大家想想,如果用簡單的字串匹配,能不能計算兩個字串的相似度呢?我想,估計是不行,因為這裡涉及到乙個字串對齊的問題。哪麼,我們如何採用ld演算法來實現字串相似度的比較呢
我打算分二塊介紹ld演算法,第一塊是求編輯距離,第二部分是回溯,找到兩個字串的差異。
ld有下面幾個性質:
ld(a,a)=0
ld(a,"")=len(a)
ld(a,b)=ld(b,a)
0≤ld(a,b)≤max(len(a),len(b))
ld(a,b)=ld(rev(a),rev(b))
ld(a+c,b+c)=ld(a,b)
ld(a+b,a+c)=ld(b,c)
ld(a,b)≤ld(a,c)+ld(b,c)(注:像不像「三角形,兩邊之和大於第三邊」)
ld(a+c,b)≤ld(a,b)+ld(b,c)
為了講解計算ld(a,b),特給予以下幾個定義
a=a1a2……an,表示a是由a1a2……an這n個字元組成,len(a)=n
b=b1b2……bm,表示b是由b1b2……bm這m個字元組成,len(b)=m
定義ld(i,j)=ld(a1a2……ai,b1b2……bj),其中0≤i≤n,0≤j≤m
故: ld(n,m)=ld(a,b)
ld(0,0)=0
ld(0,j)=j
ld(i,0)=i
對於1≤i≤n,1≤j≤m,有公式一
若ai=bj,則ld(i,j)=ld(i-1,j-1) 取矩陣對角的值
若ai≠bj,則ld(i,j)=min(ld(i-1,j-1),ld(i-1,j),ld(i,j-1))+1 在對角,左邊,上邊,取最小值+1
a=gga-tc
-g- -a
b=gaattcagtta
a串位於矩陣的左側,b串位置矩陣的上方。一般來說,長度短的命名為a,長度長的命名為b。
第一步如下:
ld演算法矩陣圖 g
aatt
cagt
ta01
2345
6789
1011g1
0123
4567
8910g
2a3t
4c5g
6a7 圖一
第二步,用第一步方法,填充其它的空格。
ld演算法矩陣圖 g
aatt
cagt
ta01
2345
6789
1011g1
0123
4567
8910g
2112
3456
6789
a321
1234
5678
8t43
2212
3456
78c5
4332
2234
567g
6544
3333
3456
a765
4444
3445
5 圖二
最右下角的數字就為編輯距離了。
我們現在以圖二為例,要說明如何回溯。
第一步:定位在矩陣的右下角
,也就是說從5開始。
第二步:回溯單元格,至矩陣的左上角
若ai=bj,則回溯到左上角單元格
若ai≠bj,回溯到左上角、上邊、左邊中值最小的單元格,若有相同最小值的單元格,優先順序按照左上角、上邊、左邊的順序
注意: 如果i或者j的值,有乙個為0,則 左上,上邊,都沒有值,只能比較左邊的值了
回溯的結果,如圖二 紅色部分所示。
第三步:根據回溯路徑,寫出匹配字串
若回溯到左上角單元格,將ai新增到匹配字串a,將bj新增到匹配字串b
若回溯到上邊單元格,將ai新增到匹配字串a,將_新增到匹配字串b
若回溯到左邊單元格,將_新增到匹配字串a,將bj新增到匹配字串b
搜尋晚整個匹配路徑,匹配字串也就完成了
a=gga-tc-g- -a
b=gaattcagtta
注意,a
i 是會對a串來說的,b
j 是會對b串來說的,最後的結果是倒序,我們要revert一下。
現在給出c的**:
#include#include #include void backtracking(int**, char* ,char*); //回溯,計算出如何通過其中乙個字串的變換,得到另外乙個字型串
int ** build_matrix(char* , char*); //求編輯距離,返回乙個已經填充好的矩陣
int trigle_min(int a, int b, int c); //求三個數的最小值
int main()
//0 左上角 ,1上方,-1左邊
int way(int i_t, int j_t, int i, int j)
if (i-i_t==1&&j-j_t==0)
if (i-i_t==0&&j-j_t==1)
}int** build_matrix(char* a, char* b)
else
else
if (matrix[i_t][j_t]>=matrix[i-1][j-1])
/
int w = way(i_t, j_t, i,j);
if (w==0) else if (w == -1) else
++k;
i=i_t;
j=j_t;
}
} if (i==0) else
for (i=max-1;i>=0;i--)
printf("\n");
for (i=max-1;i>=0;i--)
}int trigle_min(int a, int b, int c)
{ int min = a
編輯距離及編輯距離演算法
編輯距離概念描述 編輯距離,又稱levenshtein距離,是指兩個字串之間,由乙個轉成另乙個所需的最少編輯操作次數。許可的編輯操作包括將乙個字元替換成另乙個字元,插入乙個字元,刪除乙個字元。例如將kitten一字轉成sitting sitten k s sittin e i sitting g 俄...
編輯距離及編輯距離演算法
include include include using namespace std const int max 1001 int maxlen max max int maxlen string str1,string str2 return maxlen len1 len2 int main ...
編輯距離及編輯距離演算法
include include include using namespace std const int max 1001 int maxlen max max int maxlen string str1,string str2 return maxlen len1 len2 int main ...