题目描述
给你两个单词word和word2,请返回将word1转换成word2所使用的最小操作数。你可以对一个单词进行如下三种操作:
(1)插入一个字符;
(2)删除一个字符;
(3)替换一个字符;
举例
示例1: 输入: word1="horse", word2="ros" 输出:3
示例2: 输入: word1="intention", word2="execution" 输出:5
解题方法:动态规划。dp[i][j]表示word1的前i个字符和word2的前j个字符的编辑距离。若word1[i-1]=word2[j-1],则dp[i][j] = dp[i-1][j-1],否则dp[i][j]=std::min(dp[i][j-1], dp[i-1][j], dp[i-1][j-1]+1)。
代码
#include <iostream>
#include <vector>
#include <string>
int edit_distance(const std::string& str1,
const std::string& str2) {
int n1 = str1.size();
int n2 = str2.size();
if (n1 * n2 == 0) { //如果有一个字符为空,则返回另外一个字符的长度
return n1 + n2;
}
std::vector<std::vector<int> > dp(n1 + 1, std::vector<int>(n2 + 1));
// dp[i][j]表示str1的前i个字符和str2的前j个字符对应的编辑距离
dp[0][0] = 0;
for (int i = 0; i < n1; i++) {
dp[i][0] = i;
}
for (int j = 0; j < n2; j++) {
dp[0][j] = j;
}
for (int i = 1; i <= n1; i++) {
for (int j = 1; j <= n2; j++) {
if (str1[i - 1] == str2[j - 1]) { //str1的第i个字符等于str2的第j个字符
dp[i][j] = dp[i - 1][j - 1];
} else {
dp[i][j] = std::min(dp[i - 1][j - 1] + 1,
std::min(dp[i - 1][j] + 1, dp[i][j - 1] + 1));
}
}
}
return dp[n1][n2];
}
void print_result(const std::string& str1,
const std::string& str2,
int result) {
std::cout << "========" << std::endl;
std::cout << "input:" << std::endl;
std::cout << "str1:" << str1 << std::endl;
std::cout << "str2:" << str2 << std::endl;
std::cout << "edit_distance:" << result << std::endl;
}
int main()
{
// case1
std::string str1 = "horse";
std::string str2 = "ros";
int result = edit_distance(str1, str2);
print_result(str1, str2, result);
// case2
str1 = "intention";
str2 = "execution";
result = edit_distance(str1, str2);
print_result(str1, str2, result);
// case3 = ""
str1 = "1";
str2 = "";
result = edit_distance(str1, str2);
print_result(str1, str2, result);
return 0;
}
代码运行结果如下:
========
input:
str1:horse
str2:ros
edit_distance:3
========
input:
str1:intention
str2:execution
edit_distance:5