算法第三章上机实践报告

1.实践题目

 

 

 

2.问题描述

这道题要求从一个字符串变为另一字符串,一次最小的操作可以是增加一个字符,减少一个字符,或者将一个字符变为另外一个,每进行一次,距离加一,最小的距离,也就是最少操作次数即为所求。

 

3.算法描述

这道题要用到动态规划思想,类似于LCS算法:

设A,B字符串长度分别为m,n,数组c[m + 1][n + 1]记录距离,其中c[m][n]即为所求最终距离

(一).若A,B末位字符一样,则该位置的字符一定不用操作,该问题与A,B除去末位字符的子问题相同,c[m][n]=c[m - 1][n - 1];

(二).若末尾字符不一样,

   (1).对A末位进行删除,则此时c[m][n] = c[m - 1][n] + 1;

   (2).对A末位进行增添,增添的字符为B的末位,此时A有m + 1位而B有n位,但是末位相同,同理于(一),c[m][n] = c[m][n - 1] + 1

(三).当A为空时,相当于A增加n个字符,c[0][n] = n;

   当B为空时,相当于A删除m个字符,c[m][0] = m;

   当两者均为空,则无需操作c[0][0] = 0;

所以记录的数组应该是:

当i = j = 0时,c[i][j] = 0;

当i = 0, j > 0时,c[i][j] = c[0][j] = j;

i > 0, j = 0时,c[i][j] = c[i][0] = i;

当i > 0, j > 0时,c[i][j] = min(c[m - 1][n] + 1, c[m][n - 1] + 1, c[m - 1][n - 1] + ifLastDigitEqual);

当A[i - 1] == B[j - 1](末位字符相等)时,ifLastDigitEqual = 0,否则为1;

c[m][n]即为所求

代码如下:

#include<iostream>
#include<string>
#include <algorithm>
using namespace std;

int main()
{
    string A, B;
    getline(cin, A);
    getline(cin, B);
    int i, j;
    int ifLastDigitEqual;                //记录末位字符是否相等
    int **c;                            //记录表
    c = new int*[A.length() + 1];
    for (int k = 0; k <= A.length(); k++)
    {
        c[k] = new int[B.length() + 1];
    }
    for (i = 0; i <= A.length(); i++)//B为空的情况
    {
        c[i][0] = i;
    }
    for (j = 1; j <= B.length(); j++)//A为空的情况
    {
        c[0][j] = j;
    }
    for (i = 1; i <= A.length(); i++)
        for (j = 1; j <= B.length(); j++)
        {
            if (A[i - 1] == B[j - 1])
            {
                ifLastDigitEqual = 0;
            }
            else
            {
                ifLastDigitEqual = 1;
            }
            c[i][j] = min(c[i - 1][j] + 1, c[i][j - 1] + 1);
            c[i][j] = min(c[i][j], c[i - 1][j - 1] + ifLastDigitEqual);
        }
    cout << c[A.length()][B.length()];
    return 0;
}

 

4.算法时间及空间复杂度分析

用两层for循环来建表得到答案c[m][n],时间复杂度为O(n^2),建表需要m * n的空间,空间复杂度为O(n^2);

 

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

上机实践的时候还是做的比较慢,对动态规划的思想了解不透彻,做第一题的时候卡了很久,好在和同伴讨论过后完成了这道题,但是第三题课上就没时间做了,回来后参考了网上的解答再讨论了之后,又想了很久才写出来。这道题其实和最长公共子序列类似,我写代码时也参考了课本上的这最长公共子序列代码。动态规划,就是要将问题划分为子问题,将子问题的答案记录在表中。找到划分的方法确定子问题,理清思路,才能把这类问题解决好。

posted on 2019-10-20 22:16  Aozaki  阅读(120)  评论(0编辑  收藏  举报