1. 实践题目: 编辑距离问题
2. 问题描述
给出两个字符串A和B,要用最少的字符操作将字符串A转换为字符串B。字符操作包括: (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。编辑距离即将字符串A变换为字符串B所用的最少字符操作数,可记为d(A,B),求出给出的两个字符串A和B的编辑距离。
3. 算法描述
定义一个dp[i][j]数组,用于记录将 A串的前i个字符转变为B串的前j个字符 所需的编辑距离,初始化dp[i][0]=i,dp[0][j]为j,表示将A串转变为空串所需的编辑距离,以及将空串转变为B串的编辑距离。dp[i-1][j]表示删除A串中的一个字符,dp[i-1][j]表示添加A串中的一个字符,dp[i-1][j-1]表示修改A串中的一个字符,从A字符串的开头开始遍历,进行动态规划操作,取各操作中的最小值。
代码如下:
1 #include <iostream>
2 #include <cstring>
3 using namespace std;
4 int dp[10005][10005];
5 char str1[2005],str2[2005];//str1表示字符串A,str2表示字符串B
6 int main(){
7 scanf("%s",str1);
8 scanf("%s",str2);
9 int len1 = strlen(str1),len2 = strlen(str2);
10 dp[0][0]=0;//初始化dp数组
11 for(int i=1;i<=len1;i++){
12 dp[i][0]=i;
13 }
14 for(int j=1;j<=len2;j++){
15 dp[0][j]=j;
16 }
17 for(int i=1;i<=len1;i++){
18 for(int j=1;j<=len2;j++){
19 int temp=(str1[i-1]==str2[j-1]?0:1);//比较A串和B串的字符是否相同,相同则无需修改,不同则需要修改
20 dp[i][j]=min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+temp);//比较修改,删除以及添加的操作所需的编辑距离,取最小值
21 }
22 }
23 printf("%d\n",dp[len1][len2]);
24 }
4. 算法分析
空间复杂度:该动态规划算法使用了一个二维数组,其中各维的取值与字符串的长度有关,故空间复杂度为O(len1*len2)。
时间复杂度:该算法使用了两个循环进行初始化以及一个双重循环进行各元素的遍历与比较,其它操作复杂度为O(1),故时间复杂度为O(len1*len2)。
5. 心得体会
开始有些无从下手,因为认为各种操作可以从任何位置进行,没有办法缩小问题的规模,后来发现从任何一个位置开始进行队最终答案都不会有影响,所以就可以运用动态规划算法了,在和队友讨论了这一道题之后,我对动态规划又有了更深的理解,也大致明白了一些问题的固定套路。
来源:https://www.cnblogs.com/Benboys/p/9908331.html