编辑距离问题

来源:互联网 发布:淘宝订单存在异常 编辑:程序博客网 时间:2024/06/07 07:16

1. 实践题目

 编辑距离问题

2. 问题描述

设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。

3. 算法描述(不能粘贴程序)

1、子问题含义 d[i][j];//d[i][j]表示A[0:i]和B[0:j]的编辑距离

2、子问题的递归公式:

                         0             i==0&&j==0

                    d[i][0]=i        i>0&&j==0

d[i][j]=          d[0][j]=j        i==0&&j>0

                  min(m[i-1][j]+1,m[i][j-1]+1,m[i-1][j-1]+cost)i>0&&j>0

                   (cost=A[i-1]=B[j-1]?0:1)

1)若A,B均为空,则不需要做任何修改,d[i][j]=0

2)若A不为空,B为空,则需要删除A的所有内容得到B,d[i][j]=i

3) 若A为空,B不为空,则需要向A增加B的所有内容得到B,d[0][j]=j

4)若A,B两个串均不为空,则

当A[i-1]==B[j]时,需要删除A[i],d[i][j]=m[i-1][j]+1;

当A[i]==B[j-1]时,需要将B[j]加到A中,d[i][j]= m[i][j-1]+1;

当A[i-1]=B[j-1]时,d[i][j]=m[i-1][j-1]+0;否则,需要改写A[i-1],所以d[i][j]=m[i-1][j-1]+1。

此时d[i][j]= min(m[i-1][j]+1,m[i][j-1]+1,m[i-1][j-1]+cost)

 

3、原问题的最优解是 d[m][n]

 

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

时间复杂度:因为该算法是对一个(m+1)(n+1)的表格进行填写的过程,填写每一个格d[i][j]所用时间,是根据 d[i-1][j], d[i][j-1], d[i-1][j-1],进行简单的加减运算,并选择其中最小的一个。并且,结合源代码分析,其中以上程序段所用时间最长,所以算法的时间复杂度为O(m*n)。                                                           

空间复杂度: 因为该算法是对一个(m+1)(n+1)的表格进行填写的过程, 所以该算法的空间复杂度为O(m*n)。

5. 程序运行截图


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

通过本次实验,我深刻地了解到了二维数组的重要性且对于动态规划,三部曲必不可少,同时对于动态规划也有了更深入的理解,从中学习到了许多新的编程思想,很大地提高了编程效率。

7. 附录:

源代码:

#include <iostream>

using namespace std;

int main()

{

   string A,B;

   cin>>A;

   cin>>B;

   int m=A.length();

   int n=B.length();

   int x,y,z;

   static int d[2000][2000];//填表 ,d[i][j]表示A[0:i]和B[0:j]的编辑距离

 

   for(int i=0;i<=m;i++) d[i][0]=i;//填第一列

   for(int j=0;j<=n;j++)d[0][j]=j;//填第一行

   for(int i=1;i<=m;i++)

  {

     for(int j=1;j<=n;j++)

         {

           int cost=(A[i-1]==B[j-1]?0:1);

        

       x=d[i-1][j]+1;//d[i][j]上面的格

       y=d[i][j-1]+1;//d[i][j]左边的格

       z=d[i-1][j-1]+cost;//d[i][j]左上的格

       d[i][j]=min(x,min(y,z));//三个格的最小值为最少字符操作数

         }

  }

cout<<d[m][n]<<endl;

}