题目:
给定字符串 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;
}