SWUST OJ 之 0697 Edit Distance

题目

设A 和B 是2 个字符串。要用最少的字符操作将字符串A 转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。 将字符串A变换为字符串B 所用的最少字符操作数称为字符串A到B 的编辑距离,记为d(A,B)。试设计一个有效算法,对任给的2 个字符串A和B,计算出它们的编辑距离d(A,B)。

输入

第一行是字符串A,文件的第二行是字符串B。字符串长度不大于2000。

输出

输出距离d(A,B)

样例输入

fxpimu
xwr

样例输出

5

分析

我们来思考一下字符串的更改有三种方式:(1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符;
我们先可以抽象出这样一个表格:(空串变成其他串的时候需要改变的距离为字符串长度)
SWUST OJ 之 0697 Edit Distance_第1张图片SWUST OJ 之 0697 Edit Distance_第2张图片
我们单独从第三行 x 开始,x --> f(改)、x --> fx(加 f)、x --> fxp(加 f、p)…………

我们知道当两个字符相同的时候我们不做任何操作,那么这个问题就变成它们两的子问题;
即:distance(m,n) = distance(m - 1,n - 1);
两个字符不同的时候我们需要做一次操作,此时我们就要从它的三个子问题中找出最小的那个值再 + 1;
即:distance(m,n) = min(distance(m - 1,n - 1),distance(m,n - 1),distance(m - 1,n))+ 1;

依次增长字符串 A,计算每种字符串 A 变成字符串 B 时需要的编辑距离,更新表格;
这样我们就有了一个解题思路,下面我们就开始解题;

代码

// Test.cpp: 定义控制台应用程序的入口点。
//

#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
#define LL long long int
using namespace std;

int dp[10005][10005];

int main() {
	
	string str_A;
	string str_B;
	cin >> str_A >> str_B;

	int len_A = str_A.length();
	int len_B = str_B.length();
	for (int i = 0; i <= len_A; i++)//每行0列
		dp[i][0] = i;
	for (int j = 0; j <= len_B; j++)//0行每列
		dp[0][j] = j;

	for (int i = 1; i <= len_A; i++)
	{
		for (int j = 1; j <= len_B; j++)
		{
			if (str_A[i - 1] == str_B[j - 1])	//注意字符串从0开始
				dp[i][j] = dp[i - 1][j - 1];	//相同不做改变,距离为子问题距离
			else
			{					//上、左、左上最小距离 + 1
				dp[i][j] = min(dp[i - 1][j - 1], 
					min(dp[i][j - 1], dp[i - 1][j])) + 1;
			}
		}
	}
	cout << dp[len_A][len_B] << endl;

	return 0;

}

 

 

 

你可能感兴趣的:(SWUST,OJ题库,动态规划,算法练习,编程练习)