C++动态规划算法之计算字符串距离

来源:互联网 发布:python 函数作为参数 编辑:程序博客网 时间:2024/05/21 09:46

计算字符串距离

Description

对于两个不同的字符串,我们有一套操作方法来把他们变得相同,具体方法为:
  1. 修改一个字符(如把“a”替换为“b”)
  2. 删除一个字符(如把“traveling”变为“travelng”)
  3. 增加一个字符(如把“son”改成“song”
比如对于“abcdefg”和“abcdef”两个字符串来说,我们认为可以通过增加/减少一个“g”的方式来达到目的。无论增加还是减少“g”,我们都仅仅需要一次操作。我们把这个操作所需要的次数定义为两个字符串的距离。
给定任意两个字符串,写出一个算法来计算出他们的距离。

Input

第一行有一个整数n。表示测试数据的组数,
接下来共n行,每行两个字符串,用空格隔开。表示要计算距离的两个字符串
字符串长度不超过1000。

Output

针对每一组测试数据输出一个整数,值为两个字符串的距离。

Sample Input

3abcdefg  abcdefab abmnklj jlknm

Sample Output

104

题目解析

这道题的要求就是求最短编辑距离,所谓编辑距离(简称ED),是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数(编辑操作有三种:将一个字符替换成另一个字符、插入一个字符、删除一个字符)。它的公式如下:

if(a[i-1]==b[j-1])
    f[i][j]=f[i-1][j-1];
else
    f[i][j]=1+min(f[i-1][j-1],f[i][j-1],f[i-1][j]);

接下来,为了使大家更清楚最短编辑距离,我制作了3个表(样例中的3组数据),具体如下:

 0abcdef0012

3

456a1012345b2101234c3210123d4321012e5432101f6543210g7654321

 0ab0012a101b210

 0jlknm0012345m112344n222334k333234l443334j544444

代码实现

代码(DP)如下:

#include<cstdio>#include<cstring>#include<iostream>using namespace std;char a[1001],b[1001];int lena,lenb,f[1001][1001];int min(int x,int y,int z) //algorithm库的min只有两个参数(即只能对两个数进行判定),所以我自己写了一个min函数{if(x<=y&&x<=z) return x;else if(y<=x&&y<=z) return y;else return z;}main(){int n;cin>>n;  //输入测试数据数while(n--){scanf("%s%s",a,b); //本人不才,不太会用string,所以用了字符数组(用string也可以)lena=strlen(a);  //存储a字符数组的长度lenb=strlen(b);  //存储b字符数组的长度for(int i=0;i<=lena;i++)for(int j=0;j<=lenb;j++){if(!i)  //给第一列赋值{  f[i][j]=j;  continue;  }  if(!j)  //给第一行赋值{  f[i][j]=i;  continue;  } /*这里就是最短编辑距离的公式*/if(a[i-1]==b[j-1])  //若两子串的最后一个字符相等,那它们的最短编辑距离就跟删掉最后一个字符后的最短编辑距离相等f[i][j]=f[i-1][j-1];else //在替换、插入、删除中选择令两个字符串编辑距离最少的,并加上1(当末尾字符不相等时)f[i][j]=1+min(f[i-1][j-1],f[i][j-1],f[i-1][j]);}cout<<f[lena][lenb]<<endl;}}