编辑距离问题+第三章作业
一.距离编辑问题
1.问题描述:s和t是2个字符串,需要把s编辑成t,求s编辑成t的最小操作次数,即为编辑距离其中对s的操作只能有三种:
- 删除一个字符,记为1次操作
- 插入一个字符,记为1次操作
- 替换一个字符,记为1次操作
输入格式:第一行是字符串s,文件的第二行是字符串t。
输出格式:最小编辑距离(某自然数)
2.问题分析:
设字符串s长度为m;字符串t长度为n; i,j为字符下标;
D[i,j]表示s[1,i]编辑成t[1,j]的最小距离,原始问题为D[m,n]
对于三种操作:考察末尾元素
①删除:

s[1,i]删除末尾元素s[i]趋向t[1,j]; 即D[i,j]=D[i-1,j]+1
②插入:

s[1,i]末尾插入元素t[j]趋向t[1,j]; 即D[i,j]=D[i,j-1]+1
③替换:

- 若s[i]=t[j],则无替换操作; 即D[i,j]=D[i-1,j若s[i]≠t[j],则把s[i]替换成t[j]; 即D[i,j]=D[i-1,j-1]+1
3.递归方程式:
对于以上三种操作的分析可以得出递归方程式为:

(其中D[i,j-1],D[i-1,j],D[i-1,j-1]均符合动态规划的最优子结构性质)
4.填表
①表的维度:由D[i,j]格式可知,显然是二维数组
②填表范围:由i∈[0,m],j∈[0,n]可知,表的大小为m*n
③填表顺序:由递归方程式可知,表格自上而下,从左到右填写
④表的初始化:i=0时,所取s字符串为空,所以做j次插入; 即D[0,j]=j
j=0时,所取t字符串为空,所以做i次删除; 即D[i,0]=i


5.复杂度分析:
- 时间复杂度:表格大小为m*n,二重循环,故为O(m*n)
- 空间复杂度:表格大小为m*n,二维数组,故为O(m*n)
6.伪代码和具体代码:

#include<bits/stdc++.h>
using namespace std;
char s[2001], t[2001];
int d[2001][2001];
int temp = 1;
int main (){
cin >> s;
cin >> t;
int l1 = strlen (s);
int l2 = strlen (t);
for(int i = 0; i <= l1; i++) d[i][0] = i; //初始化
for(int i = 0; i <= l2; i++) d[0][i] = i;
for(int i = 1; i <= l1; i++){
for(int j = 1; j <= l2; j++){
if(s[i-1] == t[j-1]) temp = 0; //无需替换
else temp = 1; //需要替换
int m = min(d[i-1][j] + 1,d[i][j-1] + 1); //选择删除插入中最小编辑距离
d[i][j] = min(m,d[i-1][j-1] + temp); //选择替换删除插入中最小编辑距离
}
}
cout <<d[l1][l2];
return 0;
}
二.动态规划相关理解
1.解题思路:求解f(n)问题时当做f(n-1)的答案已经得知,在此基础上思考子问题和原问题的联系,从而得出递归关系式。
对动态规划的理解此处借用知乎上的回答:
问题的答案依赖于问题的规模,也就是问题的所有答案构成了一个数列。
将动态规划拆分成三个子目标:建立递归关系式;缓存并复用以往结果;按顺序从小往大算
2.递归关系式是动态规划最重要的内容!
建立了正确的递归关系式后,我们可以在运用填表法时,可以通过递归关系式得到表的大小,表的范围,填表顺序
在编写程序时,也是通过正确的递归关系式的各个部分来编写动态规划的核心算法
三.结对编程情况概述:
主要流程是一起看题交流思路,然后各自编写代码,中间有什么问题和不懂再探讨探讨,最后debug。
我主要负责编写代码,有时候只顾自己的思路,没有考虑队友有没有理解,我的问题,以后一定注意。

浙公网安备 33010602011771号