zoukankan      html  css  js  c++  java
  • 09E-计算字符串距离

    09E:计算字符串距离

    总时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述
    对于两个不同的字符串,我们有一套操作方法来把他们变得相同,具体方法为:
    1. 修改一个字符(如把“a”替换为“b”)
    2. 删除一个字符(如把“traveling”变为“travelng”)

    比如对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。无论增加还是减少“g”,我们都仅仅需要一次操作。我们把这个操作所需要的次数定义为两个字符串的距离。
    给定任意两个字符串,写出一个算法来计算出他们的距离。
    输入
    第一行有一个整数n。表示测试数据的组数,
    接下来共n行,每行两个字符串,用空格隔开。表示要计算距离的两个字符串
    字符串长度不超过1000。
    输出
    针对每一组测试数据输出一个整数,值为两个字符串的距离。
    样例输入
    3
    abcdefg  abcdef
    ab ab
    mnklj jlknm
    样例输出
    1
    0
    4
     1 #include<iostream>
     2 #include<string>
     3 #include<algorithm> 
     4 #include<cstring>
     5 using namespace std;
     6 int maxlen[1002][1002];
     7 int calc(string a, string b){
     8     memset(maxlen,0,sizeof(maxlen));
     9     int alen = a.length();
    10     int blen = b.length();
    11     for(int i = 1; i <= alen; i++){
    12         maxlen[i][0] = i;
    13     }
    14     for(int i = 1; i <= blen; i++){
    15         maxlen[0][i] = i;
    16     }
    17     for(int i = 1; i <= alen; i++){
    18         for(int j = 1; j <= blen; j++){
    19             if(a[i-1]==b[j-1]) maxlen[i][j] = maxlen[i-1][j-1];
    20             else maxlen[i][j] = min(min(maxlen[i-1][j],maxlen[i][j-1]),maxlen[i-1][j-1])+1; 
    21         }
    22     }
    23     return maxlen[alen][blen];
    24 }
    25 int main(){
    26     int n;
    27     cin>>n;
    28     while(n--){
    29         string a, b;
    30         cin>>a>>b;
    31         cout<<calc(a, b)<<endl;
    32     }
    33     return 0;
    34 }

    备注:这道题乍一看就跟最长公共子序列非常的相像。但我想错了,我本来想的是求出最长公共子序列然后max(alen,blen)-maxlen[alen][blen]就是结果,也过了样例,但这样其实是不对的,只是我举的例子都比较寸。

    比如说abcdeeef,gacdeg这两个序列,按照我的错误想法是4步,但关键就在于第一个g,使得他们的距离是5,也就是说需要先删掉g再在a后面加上b,这是两个步骤。也就是说,我最开始想的是,除了公共子序列之外,以长的那个字符串为基准,短的里面不一样的字母要么就删掉,要么就换掉,要么就添加,但这个显然跟短字符串也有关系。比如说如果短字符串是agcdeg,那么直接把第一个g改成b就行,而不需要先删除再添加这两步。

    那这道题正确的想法是什么呢?也和公共子序列很相近。array[i][j]表示a字符串的前i个字符构成的子串和b字符串前j个字符构成的子串,的最小操作数。

    对比每一个字符a[i-1]和b[j-1],若两个字符相等,即a[i-1] == b[j-1],则不增加距离,因此对应的数组array[i][j]=array[i-1][j-1];若两个字符不相等,则可删除a[i-1]这个字符、删除b[j-1]这个字符,或修改a[i-1]使它与b[i-1]相等。array[i][j]取这三种方法的最小值。选择修改,则array[i][j] = 1 + array[i-1][j-1],若选择删除a[i-1],则array[i][j] = 1 + array[i-1][j],若选择删除b[i-1],则array[i][j] = 1 + array[i][j-1]。

  • 相关阅读:
    FastAPI(38)- 模拟一个跨域场景
    FastAPI(37)- Middleware 中间件
    Python
    Python
    FastAPI(35)- 依赖项中使用 yield + Context Manager 上下文管理器
    汇编 | CPU物理地址本质理解
    汇编 | DosBox初步接触的一些初始化设置(窗口大小 & 默认命令)
    汇编语言 第3版 王爽 检测点答案及详细解析 (更新中)
    JSP | Tomcat目录结构详解
    JSP常见错误以及解决方案
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/13096757.html
Copyright © 2011-2022 走看看