算法の第三章的上机实验报告

一、实践题目

编辑距离问题

二、问题描述

输入两个字符串,使用最少的操作即最短编辑距离,将一个字符串变成另一个字符串,输出最短编辑距离


三、算法描述

1.定义:定义并输入两个字符串s,t,再定义一个二维数组dp[i][j]来记录s中第1到第i个字符,t中第1到第j个字符的最短编辑距离

2.初始化:dp[0][j]=j,dp[i][0]=i

3.填表:考虑s[i]和t[j]的关系:

      ①s[i]==t[j]时:dp[i][j]=dp[i-1][j-1](末尾有一个相同的字符时,不用操作,从各自的前一个字符开始计算)

      ②s[i]!=t[j]时:有三种操作,任意删除两个字符串其中一个的字符,即dp[i][j]=dp[i-1][j]+1 或者 dp[i][j]=dp[i][j-1]+1,修改其中一个的字符,dp[i][j]=dp[i-1][j-1]+1

     所以递归式为  D[i][j]=min ( min ( D[i-1][j]+1,D[i][j-1]+1 ),( A[j-1]==B[i-1] ? D[i-1][j-1] : D[i-1][j-1]+1 ) );(数组从0开始)       

代码如下:

#include<iostream>
#include<string>
using namespace std;
int MinEditDistance(string A,string B)
{
    int len_A = A.length();
    int len_B = B.length();
    int D[len_B+1][len_A+1];
   
 D[0][0]=0;
    for(int i=1;i<=len_A;i++)
    {
        D[0][i]=i;
    }
    for(int i=1;i<=len_B;i++)
    {
        D[i][0]=i;
    }
    for(int i=1;i<=len_B;i++)
    {
        for(int j=1;j<=len_A;j++)
            D[i][j]=min(min(D[i-1][j]+1,D[i][j-1]+1),(A[j-1]==B[i-1]?D[i-1][j-1]:D[i-1][j-1]+1));
    }
    return D[len_B][len_A];
}
int main()
{
    string A,B;
    cin>>A>>B;
    cout<<MinEditDistance(A,B);
}

四、算法时间及空间复杂度分析(要有分析过程)

       这种实现的时间复杂度和空间复杂度都是n²级别的(实际上是m×n,两个字符串长度的乘积)

  时间复杂度为o(m*n):最深的嵌套即是m*n

  空间复杂度为o(m*n):申请并填充了一个m*n的表格。


五、心得体会(对本次实践收获及疑惑进行总结)

   1. 做动态规划的题即先写出递归方程,然后解决初始化(边界)问题,再然后就基本ok了。

        2.注意main函数中不能申请太大的数组,要把这些定义到外面。

猜你喜欢

转载自www.cnblogs.com/twojiayi/p/11725820.html