zoukankan      html  css  js  c++  java
  • 算法第三章上机实践报告,编辑距离问题

    实践报告任选一题进行分析。内容包括:

    1. 实践题目
    2. 问题描述
    3. 算法描述
    4. 算法时间及空间复杂度分析(要有分析过程)
    5. 心得体会(对本次实践收获及疑惑进行总结)

    1.实践题目

    7-3 编辑距离问题 (30 分)

    2.问题描述

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

    输入格式:

    第一行是字符串A,文件的第二行是字符串B。

    提示:字符串长度不超过2000个字符。

    输出格式:

    输出编辑距离d(A,B)

    输入样例:

    在这里给出一组输入。例如:

    fxpimu
    xwrs 
    

    输出样例:

    在这里给出相应的输出。例如:

    5


    3.算法描述

    这道题是类似于最长子串匹配的题目,不过要更深入一些,首先令m[a][b]为 字符串s1下标从0到a-1组成的字符串 与 字符串从s2下标0到b-1组成的字符串的最优编辑距离,接着用动态规划的思想分析m[a][b]与它的子问题是什么关系。通过分析,我们能分析出m[a][b]的表达式:

    当s1[a-1] = s2[b-1] 当字符串s1[a-1]和s2[b-1]相等时,则不用对末位s1[a-1]和s2[b-1]进行修改操作,此时m[a][b]最优编辑距离 = m[a-1][b-1]

    当s1[a-1] != s2[b-1]时, 这时有三种情况

      1.删除末位s1[a-1]和s2[b-1],以使之s1末位与或s2末位相等,只进行一次删除操作,操作数+1,此时s1和s2的末尾元素已经相等, 只需要比较s1的前a个元素与s2的前b-1个元素,或者比较s1的前a-1个元素与s2的前b个元素,因此此时m[a][b]最优编辑距离 = m[a-1][b] + 1 或者 m[a][b-1] + 1

      2.增添一位到末位s1[a-1]和s2[b-1],使之s1末位与或s2末位相等,只进行一次增添操作,操作数+1,同理,此时m[a][b]最优编辑距离 = m[a][b-1] + 1 或者 m[a-1][b] + 1 

      3.修改一位末位s1[a-1]和s2[b-1],使之s1末位与或s2末位相等,只进行一次修改操作,操作数+1,此时s1和s2的末尾元素已经相等, 只需要比较s1的前a-1个元素与s2的前b-1个元素,则m[a][b]最优编辑距离 = m[a-1][b-1] + 1

    通过分析可以知道m[a][b]与上,左,左上元素有关,因此可以用自上而下,从左到右的填表方式填表,从而列出递推式:

    for (int i = 1; i <= b.size(); i++) {
            for (int j = 1; j <= a.size(); j++) {
                if (a[j - 1] == b[i - 1]) {
                    m[i][j] = m[i - 1][j - 1];
                }
                else {
                    m[i][j] = 1 + min(min(m[i - 1][j], m[i][j - 1]), m[i - 1][j - 1]);
                }
                
            }
        }

    继续分析发现,这个二维数组m需要初始化,边界是行、列为0的时候,

    具体化分析:

      此时有s1=“ab" , s2="" , 求m[2][0],当s2为空时, m[2][0] = 2,只要把s2进行s1字符串长度次添加操作就能将s2改为s1。

      同理有s1="",s2=”abc",求m[0][3],同上分析有m[0][3] = 3

    归纳总结有:

      m[i][0] = i

      m[0][j] = j

    综上可以写出初始化+递推过程公式:

    for (int i = 0; i <= b.size(); i++) {
            for (int j = 0; j <= a.size(); j++) {
                if (i == 0) {
                    m[i][j] = j;
                }
                else if (j == 0) {
                    m[i][j] = i;
                }
                else {
                    if (a[j - 1] == b[i - 1]) {
                        m[i][j] = m[i - 1][j - 1];
                    }
                    else {
                        m[i][j] = 1 + min(min(m[i - 1][j], m[i][j - 1]), m[i - 1][j - 1]);
                    }
                }
            }
        }

    最后,结果就保存在m[][]的最右下角

    完整代码

    int min(int a, int b) {
        return a < b ? a : b;
    }
    
    
    int main(){
        string a;
        string b;
        cin >> a;
        cin >> b;
    
        //初始化矩阵
        
        int row = 2001;
        int column = 2001;
        int **m;
        m = (int **)malloc(sizeof(int *) * row);//分配指针数组,计算行的大小
        for (int i = 0; i < row; i++)
        {
            m[i] = (int *)malloc(sizeof(int) * (column));//分配每个指针所指向的数组,再计算列
        }
        
    
    
        for (int i = 0; i <= b.size(); i++) {
            for (int j = 0; j <= a.size(); j++) {
                if (i == 0) {
                    m[i][j] = j;
                }
                else if (j == 0) {
                    m[i][j] = i;
                }
                else {
                    if (a[j - 1] == b[i - 1]) {
                        m[i][j] = m[i - 1][j - 1];
                    }
                    else {
                        m[i][j] = 1 + min(min(m[i - 1][j], m[i][j - 1]), m[i - 1][j - 1]);
                    }
                }
            }
        }
    
        cout << m[b.size()][a.size()];
    }

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

    时间复杂度分析:很简单,两层for循环,时间复杂度为O(n^2)

    空间复杂度,借助了一个n×n的二维数组,空间复杂度也为O(n^2)

    5.心得体会

    这是一道很标准的动态规划问题,重点在于列出递归方程式,只要列出了递归公式,动态规划的题目就迎刃而解。

  • 相关阅读:
    PAT 1010. 一元多项式求导 (25)
    PAT 1009. 说反话 (20) JAVA
    PAT 1009. 说反话 (20)
    PAT 1007. 素数对猜想 (20)
    POJ 2752 Seek the Name, Seek the Fame KMP
    POJ 2406 Power Strings KMP
    ZOJ3811 Untrusted Patrol
    Codeforces Round #265 (Div. 2) 题解
    Topcoder SRM632 DIV2 解题报告
    Topcoder SRM631 DIV2 解题报告
  • 原文地址:https://www.cnblogs.com/likeghee/p/11695827.html
Copyright © 2011-2022 走看看