编辑距离

题目:
给定字符串 source, target, 求 source 编辑成 target 的最短消耗,即编辑距离
替换一个字符 rc = 3
删除一个字符 dc = 3;
增加一个字符 ac = 6;

#include <iostream>
#include <stack>
#include <vector>
#include <unordered_map>

using namespace std;
int dc = 3;
int rc = 3;
int ac = 5;


int dt = 0, mt = 0;

/*
	记忆化搜索
*/
int memorized_search(const string &source, const string &target) {
    int m = source.size() + 1;
    int n = target.size() + 1;
    vector<vector<int>> dp(m, vector<int>(n, INT_MAX));

    dp[0][0] = 0;
    for (int i = 1; i < n; ++i) {
        dp[0][i] = dp[0][i - 1] + ac;
    }
    for (int j = 1; j < m; ++j) {
        dp[j][0] = dp[j - 1][0] + dc;
    }
    for (int i = 1; i < m; ++i) {
        for (int j = 1; j < n; ++j) {
            dp[i][j] = dp[i - 1][j - 1] + ((source[i - 1] == target[j - 1]) ? 0 : rc);
            int v = min(dp[i - 1][j] + dc, dp[i][j - 1] + ac);
            dp[i][j] = min(dp[i][j], v);
        }
    }
    return dp[m - 1][n - 1];
}

vector<pair<int, int>> record;

/*
	错误之极的算法
	蠢的不行
*/
int dfs1(vector<vector<int>>& prices, int i, int j, int price, const string& temp, const string &target) {
    ++mt;
//    if (prices[i][j] != INT_MAX) {
//        ++dt;
//        return prices[i][j];
//    }
    // 边界 i = 0 代表空,  i - 1 为实际取值
    if (i == temp.size() && j == target.size()) {
        return price;
    }
    if (i == temp.size()) {
        // j != target.size(), add
        while (j < target.size()) {
            price += ac;
            ++j;
        }
        return price;
    }
    if (j == target.size()) {
        while (i < temp.size()) {
            price += dc;
            ++i;
        }
        return price;
    }
    if (temp[i] == target[j]) {
        return dfs1(prices, i + 1, j + 1, price, temp, target);
    }

    // 替换
    int rp = dfs1(prices, i + 1, j + 1, price + rc, temp, target);

    // 增加
    int ap = dfs1(prices, i, j + 1, price + ac, temp, target);

    // 删除
    int dp = dfs1(prices, i + 1, j, price + dc, temp, target);


    int val = min(dp, min(rp, ap));
    prices[i][j] = min(prices[i][j], val);
    //cout << " ( " << i << " , " << j << " ) " << prices[i][j] << endl;
    return prices[i][j];
}

/*

转态: 返回dfs(i, j) 到目标态的编辑距离
心得: 写递归算法一定要定义好状态
*/

int dfs(vector<vector<int>>& prices, int i, int j, const string& temp, const string &target) {
    ++mt;
    if (prices[i][j] != INT_MAX) {
        ++dt;
        return prices[i][j];
    }
    // 边界 i = 0 代表空,  i - 1 为实际取值
    if (i == temp.size() && j == target.size()) {
        return 0;
    }
    if (i == temp.size()) {
        int price = 0;
        while (j < target.size()) {
            price += ac;
            ++j;
        }
        return price;
    }
    if (j == target.size()) {
        int price = 0;
        while (i < temp.size()) {
            price += dc;
            ++i;
        }
        return price;
    }
    if (temp[i] == target[j]) {
        return dfs(prices, i + 1, j + 1, temp, target);
    }

    // 替换
    int rp = rc + dfs(prices, i + 1, j + 1, temp, target);

    // 增加
    int ap = ac +  dfs(prices, i, j + 1, temp, target);

    // 删除
    int dp = dc + dfs(prices, i + 1, j, temp, target);


    int val = min(dp, min(rp, ap));
    prices[i][j] = min(prices[i][j], val);
    return prices[i][j];
}

int main() {
    string s = "dsdssazdasfasdsfsdfffffffffffsdsagasdsffsfgsgaddasasaffdafafg", target = "sdaasadasdadadffggggddfafsfssSaGVGDFSFSBVGaZdaZxzvgvfasfsf";
    int m = memorized_search(s, target);
    cout << m << endl;

    int M = s.size() + 1;
    int N = target.size() + 1;

    vector<vector<int>> vec(M, vector<int>(N, INT_MAX));

    int n = dfs(vec, 0, 0, s, target);
    cout << n << endl;
    cout << dt << " " << mt << endl;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值