• [作业系列]算法第3章上机实践报告


    1.实践题目

    7-3编辑距离问题

    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.算法描述

    设A串长度为l1,B串长度为l2,那么开一个dp[i][j]记录当长度为i的A串的时候变成长度为j的B串时的最短编辑距离。那么dp[0...l1][0]初始化为0...l1,dp[0][0...l2]初始化为0...l2.

    那么dp[i][j]的状态转移方程就是

      dp[i][j]=min(min(dp[i][j-1]+1,dp[i-1][j]+1),dp[i-1][j-1]+(a[i-1]!=b[j-1]));

      //也就是由dp[i][j-1]+1和dp[i-1][j]+1和dp[i-1][j-1]+(a[i-1]!=b[j-1])的最小值转移过来的;

    当时做的时候没想太多,交了一发有bug的代码但是过了,应该是样例没特意卡空串。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    const int maxn = 2005;
    char a[maxn];
    char b[maxn];
    int dp[maxn][maxn];
    int main()
    {
      cin>>a;
      cin>>b;
      int ans = 0;
      int flag = 0;
      int l1 = strlen(a);
      int l2 = strlen(b);
      if(l1==0)
        ans = l2;
      else if(l2==0)
        ans = l1;
      else
      {
    	for(int i = 1;i<=l1;i++)
    	    dp[i][0]=i;
    	for(int j =1;j<=l2;j++)
    	    dp[0][j]=j;
    	for(int i = 1;i<=l1;i++)
    	{
    		for(int j = 1;j<=l2;j++)
    		{
    			if(a[i-1]==b[j-1])
    			  flag = 0;
    			else
    			  flag = 1;
    			dp[i][j]=min(min(dp[i][j-1]+1,dp[i-1][j]+1),dp[i-1][j-1]+flag);
    		}
    	}
      }
    	cout<<dp[l1][l2]<<endl;
    }
    

      很明显上面的代码是有bug的,因为我用cin输入根本就不需要特判l1还有l2是否为0,不过当时没有在意这个细节,现附上改进代码

    #include<iostream>
    #include<cstring>
    using namespace std;
    const int maxn = 2005;
    char a[maxn],b[maxn];
    int dp[maxn][maxn];
    int main()
    {
    	cin.getline(a,2001);
    	cin.getline(b,2001);
    	int l1 = strlen(a);
    	int l2 = strlen(b);
    	for(int i = 1;i<=l1;i++)
    	  dp[i][0]=i;
    	for(int j =1;j<=l2;j++)
    	  dp[0][j]=j;
    	for(int i = 1;i<=l1;i++)
    	  for(int j = 1;j<=l2;j++)
    		dp[i][j]=min(min(dp[i][j-1]+1,dp[i-1][j]+1),dp[i-1][j-1]+(a[i-1]!=b[j-1]));
    	cout<<dp[l1][l2]<<endl;
    }
    

    4.算法时间和空间复杂度

      两层for循环,时间复杂度是O(l1*l2);

      二维dp数组,空间复杂度是O(l1*l2);

    5.心得体会

      对dp还是不够熟悉,第三题用了十来二十分钟才弄出dp方程式,如果是权哥估计看到题目没过多久就能弄出来了

    由于队内分工的时候dp是权哥搞的,所以我对dp的熟悉度不算太高,导致做题的时候用的时间比我想象中要多,感觉还是要多做一点dp的题目保持对dp的题感。(虽然正式比赛的时候dp也是权哥搞的,我最多也就和他讨论一下思路)

  • 相关阅读:
    向对象(OO)程序设计
    gVim安装vim-template插件后提示Undefined variable vim_template_subtype/Press ENTER or type command to continue
    基于JQuery easyui,gson的批量新增/修改和删除-servlet版
    Java正则表达式-匹配正负浮点数
    自己写的ORM工具
    秋色园学习测试项目
    把aspx页面生成的cs文件放到其他类库中,以实现对其的封装操作.
    杭州蚂蚁中台技术部-22届应届生-校招实习
    博客园开博
    开发随手记
  • 原文地址:https://www.cnblogs.com/kgs719/p/9895455.html
Copyright © 2020-2023  润新知