编辑距离

Description

俄罗斯科学家Vladimir Levenshtein在1965年提出了编辑距离概念。编辑距离,又称Levenshtein距离,是指两个字符串之间,由一个转成另一个所需的最少编辑操作次数。许可的三种编辑操作包括插入一个字符、删除一个字符、将一个字符替换成另一个字符。

 

至今,编辑距离一直在相似句子检索的领域中发挥着不可忽视的作用。

 

我们不妨来设计一个程序,计算两个字符串的编辑距离。

Input

每组数据有两行,每行一个字符串。

* 每个字符串长度不超过1000

* 字符串中只含小写英文字母

Output

对于每组数据,请输出一个整数表示两个字符串的编辑距离。

 

分析问题:

1.当a,b 只有两个字符串都只有一个字符时,非常简单,当a=b时,返回0,a!=b时返回1;

2.当a是一个字符,b是一个字符串时,a与b[1]相同则记为 编辑距离为t=0,反之t=2,a与b[2]比较,a=b[2]:t=t+1;

a!=b[2]:t=t;------->a=b[i]:t=t+1;a!=b[i]:t=t;最后编辑距离为t;

3.但是a='a',b='aa'时按2中方法是t=0;编辑距离确实为1。对于两个字符串,编辑距离肯定大于等于两字符串长度差的绝对值。

4,我们分析一下以下几个表: 

abababab
a01c12b11c12
b10d22c22b21

 

abcabcabcabc
c122c122b112b112
b212a123a122c221
a222c222c222d332

观察两个表中的编辑距离,可以发现规律:

n①若a[j]≠b[k]
则f[j,k]为f[j-1,k-1]、f[j-1,k]、f[j,k-1]三个数中最小数+1
n②若a[j]=b[k]
则f[j,k]=f[j-1,k-1]
n最终结果为f[la,lb](la、lb为字符串长度)

 

n对于方程①
若j=1且k≠1则f[j,k]=f[j,k-1]+1
若k=1且j≠1则f[j,k]=f[j-1,k]+1
若j=1且k=1则f[1,1]=1
n对于方程②
若j=1且k≠1则f[j,k]=f[j,k-1]
若k=1且j≠1则f[j,k]=f[j-1,k]
若k=1且j=1则f[1,1]=0

 

c语言代码实现:

#include<stdio.h>
#include<string.h>
#include<math.h>

int min_one(int left,int middle,int right) ;

int compare_Distance(char strA[],char strB[]);

int main()
{
 int distance;
 char a[100],b[100];
 gets(a); //输入两组字符串
 gets(b);
 distance=compare_Distance(a,b); //调用compare_Distance函数计算编辑距离
 printf("%d\n",distance);
 
 return 0;
}
int min_one(int left,int middle,int right)
{
 int min_one;
 if(left<=middle&&left<=right)
  min_one = left; //最右边的是最小的一个
 else if
  (middle<=right&&middle<=left) min_one=middle; //中间的一个是最小的一个
 else
  min_one = right; //右边的是最小的一个
 
 return(min_one);
}
int compare_Distance(char strA[],char strB[])
{
 int i,j;
 int m=strlen(strA);
 int n=strlen(strB);
 int L[100][100];
 if(strA[0]==strB[0])
  L[0][0]=0;
 else
  L[0][0]=1;
 for( i=1;i<m;i++) //定义第一行的距离为0到m-1
 {
 if(strA[i]==strB[0])//分两种情况
     L[i][0]=L[i-1][0];
 else
  L[i][0]=L[i-1][0]+1;
 
 }
 for( j=1;j<n;j++) //定义第一列的距离为0到n-1
 {
  if(strA[0]==strB[j])//分两种情况

   L[0][j]=L[0][j-1];
  else
   L[0][j]=L[0][j-1]+1;
 }
 for(i=1;i<m;i++)
  for(j=1;j<n;j++)
  {
   if(strA[i]==strB[j])
    L[i][j]=L[i-1][j-1]; //两个字符相同就等于上一个的距离。
   else

    L[i][j]=min_one(L[i-1][j-1],L[i-1][j],L[i][j-1])+1; //如果两个字符不相同,就是前三个最小的一个的距离。
  }
//   for(i=0;i<m;i++){
  //for(j=0;j<n;j++)
   //printf("%d ",L[i][j]);
  //printf("\n");

  }
  if(L[m-1][n-1]<abs(m-n))//解决当编辑距离小于两字符串长度差的问题
  L[m-1][n-1] = abs(m-n);
  return L[m-1][n-1];
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值