目录
-
- 问题描述
- 提示
- 代码
- 运行
- 程序流程图
- 小结
- 忠告
问题描述
给定两个字符串A和B,以及下列三种字符运算:
(1)删除一个字符(2)插入一个字符(3)将一个字符改写为另一个字符
设计算法求将A通过以上三种操作转换为B的最小次数
举例: “xy” => “xz”,只需要把 y 替换成 z,因此,最小编辑距离为 1。
“xyz” => “xy”,只需要删除 z ,请设计动态规划算法。
提示
- 如果 a[m] === b[n],那么问题转化为求解:a[1]a[2]…a[m-1] => b[1]b[2]…b[n-1] 的最小编辑距离,因此 d[m][n] === d[m-1][n-1]。比如,“xyz” => “pqz” 的最小编辑距离等于 “xy” =>“pq” 的最小编辑距离。
- 如果 a[m] !== b[n],又分为三种情况: ? 比如,“xyz” => “efg” 的最小编辑距离等于 “xy” => “efg” 的最小编辑距离 + 1(因为允许插入操作,插入一个 “z”),抽象的描述便是 d[m][n] === d[m-1][n] + 1。
? 比如,“xyz” => “efg” 的最小编辑距离等于 “xyzg” => “efg” 的最小编辑距离 +1,且因为最后一个字符都是 “g”,根据第一个判断条件,可以再等于 “xyz” => “ef” 的最小编辑距离 +1,因此,得到结论:“xyz” => “efg” 的最小编辑距离等于 “xyz” => “ef” 的最小编辑距离 +1,抽象的描述便是:d[m][n] === d[m][n-1] + 1。 ? 比如,“xyz” => “efg” 的最小编辑距离等于"xyg" => “efg” 的最小编辑距离 + 1(因为允许替换操作,可以把 “g” 换成 “z”),再等于 “xy” => “ef”
的编辑距离 + 1(根据第一个判断条件),抽象的描述便是: d[m][n] === d[m-1][n-1] + 1。
上述三种情况都有可能出现,因此,取其中的最小值便是整体上的最小编辑距离。- 如果 a 的长度为 0,那么 a => b 的最小编辑距离为 b 的长度;反过来,如果 b 的长度为 0,那么 a => b 的最小编辑距离为 a 的长度。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #include<bits/stdc++.h> //#include <iostream> //#include <string.h> //#include <vector> //#include <algorithm>//min()包含头文件 using namespace std; int main(){<!-- --> char str1[1025],str2[1025];//长度不超过1024,长度最小要声明为1024+1,因为字符串末尾有空字符。 int n,m,temp; while(cin>>str1>>str2){<!-- -->//循环输入两个字符串 m=strlen(str1); n=strlen(str2); vector<vector<int> > dp(m+1,vector<int>(n+1,0));//生成一个m+1行n+1列的二维矩阵记录当前的状态值 //初始化 for(int i=1;i<=m;i++)//dp[i][0]=i,例如dp[2][0]表示一个长度为2的字符串str1与一个空字符串str2的最小编辑距离为2(即依次将str1中的字符添加到str2中) dp[i][0]=i; for(int j=0;j<=n;j++)//dp[0][j]=j,例如dp[0][1]表示一个空字符串str1与一个长度为1的字符串str2的最小编辑距离为1(即依次将str2中的字符添加到str1中) dp[0][j]=j; dp[0][0]=0;//空字符串与空字符串之间的最小编辑距离为0 for(int i=1;i<=m;i++){<!-- --> for(int j=1;j<=n;j++){<!-- --> if(str2[j-1]==str1[i-1])//注意:字符串str1和str2中的索引是从0开始的,而1<=i<=m,1<=j<=n,所以这里的i和j要减1 dp[i][j]=dp[i-1][j-1]; else{<!-- --> temp=min(dp[i][j-1],dp[i-1][j]); dp[i][j]=min(temp,dp[i-1][j-1])+1; } } } cout<<dp[m][n]<<endl;//最终的dp[m][n]为两字符串之间的最小编辑距离 } return 0; } |
运行
(1)
(2)
(3)
程序流程图
小结
(1) 要用动态规划算法解决问题,要求该问题应该具有“最优子结构”和“重叠子问题”这两个基本要素;
(2) 在用动态规划算法自顶向下解决问题时,每次产生的子问题并不总是新问题,有些子问题被重复计算。而正是利用子问题重叠的性质,对每个子问题只解一次,然后将其保存在一个表格中。本题中正是将求出来的“最小编辑距离”保存在一个动态的可变数组中;
(3) “备忘录方法”正是用表格保存已解决的子问题的答案,在下次需要解决此子问题时,只需简单地查看该子问题的解答,而不必重复计算。
忠告
各位在借鉴时(实验报告)最好不要完全一样喔!!!!!!!!!