您的位置:首页 > 其它

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

2017-12-16 23:35 141 查看
#include <stdio.h>

/**
* 对于序列S和T,它们之间距离定义为:对二者其一进行几次以下的操作
* (1)删去一个字符;(2)插入一个字符;(3)改变一个字符。每进行一次操作,计数增加1。
* 将S和T变为同一个字符串的最小计数即为它们的距离。给出相应算法。
*/
#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个字符组成的字符串与字符串t前j个字符组成的字符串
* 每次对其一进行以下其中一项操作: (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;
//i和j大于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));
}

//递归+记忆数组的dp
static 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];

//i和j大于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:4
solve_2:4
solve_3:4
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: