【2013一道百度的笔试题】两个字符串操作多少步后变成一样的(编辑距离)

/*
 *
 *题目:
 *给定字符函数   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~

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值