题意:
编辑距离问题就是给两个字符串;
如:
abcdef
abbefc
通过增、删、改三种方式使第二个字符串变成第一个字符串;
显然此样例为 3 次改动;
题目求给定的字符串以后最少的改动次数;
理解:
一看这题其实已经蒙了;
当然有一种方法可以做,就是广搜;
但广搜在时间上是解决不了问题的;
所以得另谋出路;
正真的具体的解题思路如下:
首先:
我们向两个字符串添加一些下划线;
则:
abcdef_
ab_befc
可看出:
通过增删改很明显可以转化过去;
那么什么情况增、什么情况改、什么情况删呢?
我们现设一个需要改动的最小值 f(i, j);
表示在第一个字符串的 i 与第二个字符串的 j 字符之间存在的最小改动;
我们知道如果 str1[i] == str2[j] 的话;
则:f(i, j) = f(i - 1, j - 1);
如果不等的话;
则:f(i, j) = f(i - 1, j - 1) + 1;
这就是改;
而在前 i 个字符与前 j - 1 个字符相同了,那么就要删;
如:
abab
ababc
则:f(i, j) = f(i, j - 1) + 1;
而在前 i - 1 个字符于前 j 个字符相同了,那么就要添;
ababa
abab
则:f(i, j) = f(i - 1, j) + 1;
最后两个难以理解,但是是不可缺的;
这样,我们就可以通过上述三个式子求出一个最小值;
答案就是最小值了;
代码如下:
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const double MIN_INF = 1e-7;
const int MAX_INF = (1e9) + 7;
#define X first
#define Y second
int main() {
string str1, str2;
cin >> str1 >> str2;
int len1 = str1.length(), len2 = str2.length();
vector<vector<int> > dp(len1 + 2, vector<int>(len2 + 2, 0));
for (int i = 1; i <= len1; ++i) { // 初值
dp[i][0] = i;
}
for (int i = 1; i <= len2; ++i) { // 初值
dp[0][i] = i;
}
for (int i = 1; i <= len1; ++i) {
for (int j = 1; j <= len2; ++j) {
if (str1[i - 1] == str2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1];
}
else {
dp[i][j] = min(dp[i - 1][j - 1], min(dp[i - 1][j], dp[i][j - 1])) + 1;
}
}
}
cout << dp[len1][len2] << endl;
return 0;
}