動態規劃求解-將字串A變換為字串B 所用的最少字元操作次數
阿新 • • 發佈:2018-12-31
問題描述:
設A 和B 是2 個字串。要用最少的字元操作將字串A 轉換為字串B。
這裡所說的字元操作包括
(1)刪除一個字元;
(2)插入一個字元;
(3)將一個字元改為另一個字元。
將字串A變換為字串B 所用的最少字元操作次數也稱為字串A到B 的編輯距離,記為 d(A,B)。
試設計一個有效演算法,對任給的2 個字串A和B,計算出它們的編輯距離d(A,B)。
思路:
使用動態規劃演算法
開一個二維陣列d[i][j]來記錄a0-ai與b0-bj之間的編輯距離,要遞推時,需要考慮對其中一個字串的刪除操作、插入操作和替換操作分別花費的開銷,從中找出一個最小的開銷即為所求。
具體演算法:
首先給定第一行和第一列,然後,每個值d[i,j]這樣計算:d[i][j] = min(d[i-1][j]+1,d[i][j-1]+1,d[i-1][j-1]+(s1[i] == s2[j]?0:1));
最後一行,最後一列的那個值就是最小編輯距離
圖解:
例如要找出字串“abcdefg”與“aabcg”之間的最小編輯距離。下圖給出二維陣列d[i][j]的變化情況。
程式碼:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int GetMinNum(int a, int b, int c)//獲取三個數中最小數
{
int min = a < b ? a : b;
return min < c ? min : c;
}
void MinDistance(char *s1, int len1, char *s2, int len2)
{
int i = 0;
int j = 0;
int **d = (int **)malloc(sizeof(int*)*len1);
for (i = 0; i < len1; i++)
{
d[i] = (int*)malloc(sizeof(int )*len2);
}
for (i = 0; i <len1; i++)
{
d[i][0] = i;
}
for (j = 0; j < len2; j++)
{
d[0][j] = j;
}
for (i = 1; i < len1; i++)
{
for (j = 1; j <len2; j++)
{
int cost = (s1[i] == s2[j] ? 0 : 1);
int del = d[i - 1][j] + 1;
int insert = d[i][j - 1] + 1;
int sub = d[i - 1][j - 1] + cost;
d[i][j] = GetMinNum(del, insert, sub);
}
}
printf("%s and %s min distance is: %d\n", s1, s2, d[len1 - 1][len2 - 1]);
}
int main()
{
char s1[] = "abcdefg";
char s2[] = "aabcg";
MinDistance(s1, strlen(s1), s2, strlen(s2));
system("pause");
return 0;
}