动态规划专题5——编辑距离

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_44771588/article/details/102713280

一、问题描述:设A和B是两个字符串,需要用最少的字符操作将字符串A转换为字符串B。这些操作包括:
(1)删除一个字符;
(2)插入一个字符;
(3)将一个字符修改为另一个字符。
将字符串A变换为字符串B所用的最少字符操作数称为字符串A和B的编辑距离,记为d(A,B)。设计有效算法,对任给的2个字符串A和B,计算它们的编辑距离。
样例输入:fxpimu、xwrs
样例输出:5
二、问题分析:不用管他三种方法是怎么操作的。
我们用d[i][j]表示A[1…i]和B[1…j]的编辑距离,则有:
1、如果 A[ i ] == B[ j ],则d[ i ][ j ] = dp[i-1][j-1];
2、如果A[ i ] != B[ j ], 则有三种情况:(即上面的三种情况)
(1)删除一个字符:dp[i][j] = dp[i-1][j] +1;(因为行是A,删除一个元素就是删除一行,然后编辑距离次数+1)
(2)插入一个字符:dp[i][j] = dp[i][j-1] + 1;(插入一个字符,因为要求dp[i][j],如果增加了一行的话,dp[i+1][j]是还没有填的,解决方法就是把插入一行相当于B减少一列,同理,上面也可以这样理解)
(3)将一个字符修改成另一个字符:dp[i][j] = dp[i-1][j-1]+1;(修改肯定是朝着使字符串相等的方向修改对吧,那么相等的话就是A[i] ==B[j]的情况,不过编辑距离增加了一步)
三、状态转移方程

dp[i][j] = min(dp[i-1][j] + 1, min(dp[i][j-1] + 1, dp[i-1][j-1]+1));	

四、子问题:就是A中第一个元素开始对B的每个元素比较,看是否相等。然后看第二个,第三个。。。。。。(填表操作)
五、代码:我这里是dp[i+1][j+1],这是因为我的一种习惯而已,我习惯from 0 to n,这种循环。如果喜欢dp[i][j]这样的,循环就得from 1 to n。

#include<stdio.h>
#define min(x,y) (x) < (y) ? (x) : (y)
char A[101] = {'f','x','p','i','m','u'};
char B[101] = {'x','w','r','s'};
int na = sizeof(A) / sizeof(A[0]);
int nb = sizeof(B) / sizeof(B[0]);
int dp[102][102];
void solve()
{
	for(int i = 0; i <= na; i++)
		for(int j = 0; j <= nb; j++)
		{
			if(A[i] == B[j]) 
				dp[i+1][j+1] = dp[i][j];
			else
				dp[i+1][j+1] = min(dp[i][j + 1] + 1, min(dp[i+1][j] + 1, dp[i][j] + 1));
		}
	printf("%d\n",dp[na][nb]);
}
int main()
{
	solve();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_44771588/article/details/102713280