【动态规划】之字符串编辑距离(难度:2星)

来源:互联网 发布:ata办公软件视频 编辑:程序博客网 时间:2024/05/21 17:56

#include <stdio.h>/** * 对于序列ST,它们之间距离定义为:对二者其一进行几次以下的操作 * (1)删去一个字符;(2)插入一个字符;(3)改变一个字符。每进行一次操作,计数增加1 * ST变为同一个字符串的最小计数即为它们的距离。给出相应算法。 */#define MIN(x,y) (x<y?x:y)#define INF 50000#define SL 7     //字符串s的有效长度#define TL 5     //字符串t的有效长度static char s[SL+2] = " acbdepo";static char t[TL+2] = " abcde";/** * 我的思路如下 * 设子问题为:请求出字符串s的前i个字符组成的字符串与字符串tj个字符组成的字符串 * 每次对其一进行以下其中一项操作: (1)删去一个字符;(2)插入一个字符;(3)改变一个字符。 * 每次操作后操作数+1,最终使两个字符串相等,求最小的操作数minSum * 找出边界:显然i=0,minSum=j,因为i=0,所需要的就是连续插入j次对应字符串t的字符, * 同理j=0时也一样 *///递归int solve_1(int i, int j){    if (i == 0)        return j;    if (j == 0)        return i;    //ij大于0的情况    int cost = s[i] == t[j] ? 0 : 1;    int del = solve_1(i-1, j) + 1;    int add = solve_1(i, j-1) + 1;    int upd = solve_1(i-1, j-1) + cost;    return MIN(del, MIN(add, upd));}//递归+记忆数组的dpstatic int memo[SL+1][TL+1];int solve_2(int i, int j){    if (i == 0)        return memo[i][j] = j;    if (j == 0)        return memo[i][j] = i;    if (memo[i][j] < INF)        return memo[i][j];    //ij大于0的情况    int cost = s[i] == t[j] ? 0 : 1;    int del = solve_2(i-1,j) + 1;    int add = solve_2(i,j-1) + 1;    int upd = solve_2(i-1,j-1) + cost;    return memo[i][j] = MIN(del, MIN(add, upd));}//递推static int dp[SL+1][TL+1];int solve_3(){    for (int i = 0; i <= SL; ++i) {        dp[i][0] = i;    }    for (int j = 0; j <= TL; ++j) {        dp[0][j] = j;    }    for (int i = 1; i <= SL; ++i) {        for (int j = 1; j <= TL; ++j) {            if (s[i] == t[j])                dp[i][j] = dp[i-1][j-1];            else{                int del = dp[i-1][j] + 1;                int add = dp[i][j-1] + 1;                int upd = dp[i-1][i-1] + 1;                dp[i][j] = MIN(del, MIN(add, upd));            }        }    }    return dp[SL][TL];}int main() {    printf("solve_1:%d\n", solve_1(SL, TL));    for (int i = 0; i <= SL; ++i) {        for (int j = 0; j <= TL; ++j) {            memo[i][j] = INF;        }    }    printf("solve_2:%d\n", solve_2(SL, TL));//    for (int i = 0; i <= SL; ++i) {//        for (int j = 0; j <= TL; ++j) {//            printf("%d ",memo[i][j]);//        }//        printf("\n");//    }    printf("solve_3:%d\n", solve_3());    return 0;}

运行结果:

solve_1:4solve_2:4solve_3:4




原创粉丝点击