Edit Distance(編輯距離)算法。計算兩個字符串的相似程度。

最近需要做兩個字符串的相似度比較,涉及到了這個算法,於是寫一篇博客記錄一下。

      算法簡介

Edit Distance 算法,又稱Levenshtein Distance(LD)算法,以下簡稱LD,LD 可以衡量兩字符串的相似性。

     距離的概念

      算法裏主要涉及的就是一個距離的概念(名字裏帶的就是。。)
      距離,就是對於當前的兩個字符串,要從一個字符串轉換成另一個字符串的過程中的添加、刪除、修改的次數。
     比如: 
                                            string_1 = "abc"; 
                                            string_2 =  "abd";
       則,從string_1 轉換到string_2 只需要 把 字符‘c’,轉換成字符 'd'就行了,這只需要一次修改。於是string_1 到string_2 的距離是 1。
      顯然,當兩個字符串的距離越大,這兩個字符串的相似度就越低。

算法的思路

   先求出這兩個字符串的長度。 
                                                    int m = string_1.length();
                                                    int n = string_2.length();
    顯然,若 m,n中有一個是0,就不用比了,返回另一個的長度就行了。(顯然這就是距離了)。
    若都不是0,那麼,需要計算string_1 到string_2 需要修改多少遍了。於是,爲了計算方便,
    初始化一個 (M+1)*(N+1)的矩陣來存     int[][] different = new int[m+1][n+1];
     注意,這個時候,爲了高效計算,需要將  different 數組的第一行 也就是different[i][0]和第一列也就是different[0][i] 隨i,從0開始遞增。
   接下來就是處理字符串了。 從頭開始掃描這兩個字符串,用 i,j來分別表示掃描到了string_1 和string_2的位置。
  這時候,需要一個臨時變量來記錄 兩個字符串中的某一位置的字符時候一樣。
       int temp = 1;//  1表示不同,0,表示相同。
   顯然: 
       if(string_1[i]==string_2[j]){
                   temp = 0;
       }else{
              temp = 1;
             }
  接下來就是關鍵了:
   我們需要從  different [i-1][j]+1,  different [i][j-1]+1,和 different[i-1][j-1]+temp 中選一個最小的將它的值賦給different [i][j]; 
掃描完之後,我們就可以來計算這兩個字符串的相似度了。顯然,它們最大的距離就是 這兩個字符串的長度的大的那個長度。
資料顯示,一般,將兩個字符串的相似度定義爲: 1-它們的距離/這兩個字符串長度的最大值

算法實現

  mfc中Edit Distance算法的實現
float CMy0121124829Dlg::Similarity(CString string_1, CString string_2)
{
	int m = string_1.GetLength();
	int n = string_2.GetLength();
	int** different;
	try
	{
		different  = new int*[m+1];
		for (int i=0; i<=m; i++)
		{
			different[i] = new int[n+1];
		} 
	}
	catch (const std::bad_alloc& e)
	{
		MessageBox(_T("內存不足,請重啓程序後再試!"));
	}
	
	
	for (int i = 0; i <= m; i++) { 
		different[i][0] = i;
	} 
	for (int i = 0; i <= n; i++) { 
		different[0][i] = i; 
	} 
	int temp; 
	for (int i = 1; i <= m; i++){

		for (int j = 1; j <= n; j++){ 
			if (string_1[i - 1] == string_2[j - 1]) {
				temp = 0; 
			}
			else { 
				temp = 1; 
			} 
			different[i][j] = Min_in_three(different[i - 1][j - 1] + temp, different[i][j - 1] + 1, different[i - 1][j] + 1); 
		} 
	} 
	int dif = different[m][n];
	for (int i=0; i<=m; i++)
	{
		delete different[i];
	} 
	delete different;
	return 1 - (float)dif/ ((string_1.GetLength()>string_2.GetLength()?string_1.GetLength(): string_2.GetLength()));
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章