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]。

原文地址:https://www.cnblogs.com/fangziyuan/p/13096757.html