/*
*
*题目:
*给定字符函数 a、插入 b、删除 c、替换
*例如字符串A=acegf,字符串B=adef,最少需要2步操作将A转换为B,
*即第一步将c替换为d,第二步将g删除;
*(1)请问将字符串A=gumbo转换为字符串B=gambol,最少需要几步操作,列出如何操作(2分)
*(2)任意字符串A和字符串B,如何计算最小操作次数,计算思路,并给出递归公式(3分)
*(3)实现代码(注意代码风格与效率)(15分)
*
*/
解题思路:DP~
自己写了两个版本,一个空间上进行了改进,代码如下所示~
#include <iostream>
#include <string>
using namespace std;
const int MAX = 100;
int dp[MAX][MAX]; //dp[i][j]代表字符串s1为i个元素,s2为j个元素时,需要进行的最小操作次数
int dp2[MAX];
int Min(int x, int y)
{
return x<y ? x : y;
}
int CountMinDistance(string s1, string s2) // O(N*M)的空间,O(N*M)的时间
{
int len1 = s1.length(),len2 = s2.length();
for(int i=0; i<=len1; i++) //当s2的长度为0时,需要进行的最小操作次数即为s1的元素个数
dp[i][0] = i;
for(int i=0; i<=len2; i++) //当s1的长度为0时,需要进行的最小操作次数即为s2的元素个数
dp[0][i] = i;
//begin to work
int cost;
for(int i=1; i<=len1; ++i)
for(int j=1; j<=len2; ++j)
{
cost = (s1[i-1] == s2[j-1]) ? 0 : 1;
dp[i][j] = Min(dp[i-1][j] + 1, Min(dp[i][j-1]+1, dp[i-1][j-1] + cost));
}
//return the answer
return dp[len1][len2];
}
int CountMinDistance2(string s1,string s2) // O( Min( s1.length(),M.length() ) )的空间, O(N*M)的时间
{
int len1 = s1.length(),len2 = s2.length();
for(int i=0; i<=len2; i++) //当s1的长度为0时,需要进行的最小操作次数即为s2的元素个数
dp2[i] = i;
//begin to work
int cost,tmp,temp;
for(int i=1; i<=len1; ++i)
{
for(int j=1; j<=len2; ++j)
{
cost = (s1[i-1] == s2[j-1]) ? 0 : 1;
if(j == 1)
{
tmp = dp2[j];
dp2[j] = Min(dp2[j]+1, Min(i-1+cost, i+1));
}
else
{
temp = dp2[j];
dp2[j] = Min(dp2[j]+1, Min(dp2[j-1]+1, tmp+cost));
tmp = temp;
}
}
}
//result the answer
return dp2[len2];
}
int main()
{
string s1,s2;
while(cin>>s1>>s2)
{
cout<<CountMinDistance(s1, s2)<<endl;
cout<<CountMinDistance2(s1, s2)<<endl;
}
}
欢迎读者留言探讨~O(∩_∩)O~