(2014-2)计算两个字符串的编辑距离

问题描述:

把两个字符串变成相同的三个基本操作定义如下:

1.  修改一个字符(如把a  变成b)

2.  增加一个字符(如abed  变成abedd)

3.  删除一个字符(如jackbllog  变成jackblog)

针对于jackbllog 到jackblog  只需要删除一个或增加一个l  就可以把两个字符串变为相同。把这种操作需要的最小次数定义为两个字符串的编辑距离L。编写程序计算指定文件中字符串的距离。输入两个长度不超过512 字节的ASCII 字符串,在屏幕上输出字符串的编辑距离。

输入样例:

输入:

Hello world!
Hello word!

输出:

1

思路:

DP问题:具体思路 两个字符串的编辑距离-动态规划方法

用 dp[i][j] 表示到str1的第i个字符与str2的第j个字符的编辑距离,可以得到如下的动态规划方程:

   其中, 

首先我们令word1和word2分别为:michaelab和michaelxy

扫描二维码关注公众号,回复: 5384544 查看本文章
  1. dis[0][0]表示word1和word2都为空的时候,此时他们的Edit Distance为0。 
  2. dis[0][j]就是word1为空,word2长度为j的情况,此时他们的Edit Distance为j,也就是从空,添加j个字符转换成word2的最小Edit Distance为j
  3. 同理dis[i][0]就是,word1长度为i,word2为空时,word1需要删除i个字符才能转换成空,所以转换成word2的最小Edit Distance为i
  4. 对于上面例子最后一位:如果b==y, 那么:dis[i][j] = dis[i-1][j-1]。                                                              
        如果b!=y,那么:添加:也就是在michaelab后面添加一个y,那么word1就变成了michaelaby,此时  dis[i][j] = 1 + dis[i][j-1];删除:也就是将michaelab后面的b删除,那么word1就变成了michaela,此时dis[i][j] = 1 + dis[i-1][j];替换:也就是将michaelab后面的b替换成y,那么word1就变成了michaelay,此时dis[i][j] = 1 + dis[i-1][j-1];
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

const int N = 10010;
int dp[N][N];

int calculateStrDistance(string sA, string sB)
{
	int lA = sA.length(), lB = sB.length();
	//边界
	for (int i = 0; i <= lA; ++i)
	{
		dp[i][0] = i;
	}
	for (int j = 0; j <= lB; ++j)
	{
		dp[0][j] = j;
	}

	/*求中间的编辑距离值*/
	for (int i = 1; i <= lA; ++i)
	{
		for (int j = 1; j <= lB; ++j)
		{
			int flag = 0;
            //字符串从0开始存储
			if (sA[i - 1] != sB[j - 1])
			{
				flag = 1;
			}
            //状态转移方程
			dp[i][j] = min(dp[i - 1][j - 1] + flag, min(dp[i - 1][j] + 1, dp[i][j - 1] + 1));
		}
	}
	return dp[lA][lB];
}


int main()
{
    string sA, sB;
    getline(cin, sA);
    getline(cin, sB);
	cout << calculateStrDistance(sA, sB) << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_35093872/article/details/88074371