编辑距离及编辑距离算法

编辑距离及编辑距离算法

编辑距离概念描述:

编辑距离,又称Levenshtein距离,是指两个字串之间,由一个转成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。

例如将kitten一字转成sitting:

  1. sitten (k→s)
  2. sittin (e→i)
  3. sitting (→g)

俄罗斯科学家Vladimir Levenshtein在1965年提出这个概念。

 

问题:找出字符串的编辑距离,即把一个字符串s1最少经过多少步操作变成编程字符串s2,操作有三种,添加一个字符,删除一个字符,修改一个字符

 

解析:

首先定义这样一个函数——edit(i, j),它表示第一个字符串的长度为i的子串到第二个字符串的长度为j的子串的编辑距离。

显然可以有如下动态规划公式:

  • if i == 0 且 j == 0,edit(i, j) = 0
  • if i == 0 且 j > 0,edit(i, j) = j
  • if i > 0 且j == 0,edit(i, j) = i
  • if i ≥ 1  且 j ≥ 1 ,edit(i, j) == min{ edit(i-1, j) + 1, edit(i, j-1) + 1, edit(i-1, j-1) + f(i, j) },当第一个字符串的第i个字符不等于第二个字符串的第j个字符时,f(i, j) = 1;否则,f(i, j) = 0。

 

 

  0 f a i l i n g
0                
s                
a                
i                
l                
n                

 

 

  0 f a i l i n g
0 0 1 2 3 4 5 6 7
s 1              
a 2              
i 3              
l 4              
n 5              

 计算edit(1, 1),edit(0, 1) + 1 == 2,edit(1, 0) + 1 == 2,edit(0, 0) + f(1, 1) == 0 + 1 == 1,min(edit(0, 1),edit(1, 0),edit(0, 0) + f(1, 1))==1,因此edit(1, 1) == 1。 依次类推:

  0 f a i l i n g
0 0 1 2 3 4 5 6 7
s 1 1 2 3 4 5 6 7
a 2 2            
i 3              
l 4              
n 5              

edit(2, 1) + 1 == 3,edit(1, 2) + 1 == 3,edit(1, 1) + f(2, 2) == 1 + 0 == 1,其中s1[2] == 'a' 而 s2[1] == 'f'‘,两者不相同,所以交换相邻字符的操作不计入比较最小数中计算。以此计算,得出最后矩阵为:

  0 f a i l i n g
0 0 1 2 3 4 5 6 7
s 1 1 2 3 4 5 6 7
a 2 2 1 2 3 4 5 6
i 3 3 2 1 2 3 4 5
l 4 4 3 2 1 2 3 4
n 5 5 4 3 2 2 2 3
//主要二维数组的动态分配与释放操作
#include<iostream>
using namespace std;

int min(int a,int b)
{
	return a<b?a:b;
}
int edit(char *s,char *t)
{
	int len1=strlen(s);
	int len2=strlen(t);
	int **location=new int*[len1];
	int i,j,d,temp;
	for(i=0;i<len1;i++)
	{
		location[i]=new int[len2];
	}
	for(i=0;i<len1;i++)
	{
		location[i][0]=i;
	}
	for(i=0;i<len2;i++)
		location[0][i]=i;
	for(i=1;i<len1;i++)
	{
		for(j=1;j<len2;j++)
		{
			temp=min(location[i-1][j]+1,location[i][j-1]+1);
			if(s[i-1]==t[j-1])
				d=0;
			else
				d=1;
			location[i][j]=min(temp,location[i-1][j-1]+d);
		}
	}
	for(i=0;i<len1;i++)
	{
		for(j=0;j<len2;j++)
		{
			cout<<location[i][j]<<" ";
		}
		cout<<endl;
	}
	int dis=location[len1-1][len2-1];
	for(i=0;i<len1;i++)
	{
		delete [] location[i];
		location[i]=NULL;
	}
	delete [] location;
	location=NULL;
	return dis;
}

int main()
{
	char str1[100],str2[100];
	cin>>str1;
	cin>>str2;
	cout<<edit(str1,str2)<<endl;
	return 1;
}

转载:http://www.cnblogs.com/biyeymyhjob/archive/2012/09/28/2707343.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值