1. 程式人生 > >動態規劃求解-將字串A變換為字串B 所用的最少字元操作次數

動態規劃求解-將字串A變換為字串B 所用的最少字元操作次數

問題描述:
設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; }