700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > LD(Levenshtein distance)莱文斯坦距离----编辑距离

LD(Levenshtein distance)莱文斯坦距离----编辑距离

时间:2021-10-07 02:48:15

相关推荐

LD(Levenshtein distance)莱文斯坦距离----编辑距离

链接:/acm/contest/327/G

来源:牛客网

G处女座与复读机

题目描述

一天,处女座在牛客算法群里发了一句“我好强啊”,引起无数的复读,可是处女座发现复读之后变成了“处女座好强啊”。处女座经过调查发现群里的复读机都是失真的复读机,会固定的产生两个错误。一个错误可以是下面的形式之一:

将任意一个小写字母替换成另外一个小写字母

在任意位置添加一个小写字母

删除任意一个字母

处女座现在在群里发了一句话,他收到了一个回应,他想知道这是不是一个复读机。

/*

算法简介:

莱文斯坦距离是两个字符串序列的距离度量。形式化地说,是由一个单词变为另一个单词需要的最小编辑次数(编辑方式:插入,删除,替换)。所以莱文斯坦距离也称为编辑距离。

定义:

两个字符串a,b之间的莱文斯坦距离为:

如果

min(i,j) = 0;

levab(i,j) = max(i,j);

{length_a = 0 || lenth_b = 0,levab(a,b) = max(length_a,length_b);}

否则,

t = min(levab(i-1,j)+1,levab(i,j-1)+1);

levab = min( t,levab(i-1,j-1) + ( ai!= bj ) );

{

如果ai != bj,编辑数+1,否则+0;

}

为了实现上述定义,我们用dp[i][j]来存s1[1…i]变成s2[1…j]需要的最小编辑数

得出公式:

i = 0:

dp[i][j] = j;

j = 0:

dp[i][j] = i;

i,j都不为0:

dp[i][j] = min(min(dp[i-1][j] + 1,dp[i][j-1] + 1),dp[i-1][j-1] + (s1[i] != s2[j] ) );

公式理解:

1.

i == 0 || j==0好理解,有一个为空串,当然最小编辑数就是非空串的长度

2.

对于i,j都非零的情况,分三种情况:

1)假设s1[1…i-1] 变换到s2[1…j]需要最小的操作数为dp[i-1][j] = k,那么对于dp[i][j] = k+1,那么s1i就多余了,只需将s1中s1i删除

2)假设s1[1…i] 变换到s2[1…j-1]需要最小的操作数为dp[i-1][j] = k,那么对于dp[i][j] = k+1,只需在s1中s1i后插入s2j

3)假设s1[1…i-1] 变换到s2[1…j-1]需要最小的操作数为dp[i-1][j] = k,那么dp[i][j]可能需要编辑也可能不需要编辑,要看s1i 是否等于s2j,如果不相等,那就要把s1i替换成s2j,否则不需要编辑,所以dp[i][j] = k + (s1i!= s2j);

*/

ac_code:

#include <iostream>#include <string>#include <algorithm>using namespace std;int dp[105][105];int main(){string s1,s2;while(cin>>s1>>s2){int length1 = s1.size(),length2 = s2.size();for(int i = 0; i < length1; i++)dp[i][0] = i;for(int j = 0; j < length2; j++)dp[0][j] = j;int temp;for(int i = 1; i <= length1; i++){for(int j = 1; j <= length2; j++){temp = min(dp[i-1][j],dp[i][j-1]) + 1;dp[i][j] = min(temp,dp[i-1][j-1]+(s1[i-1]!=s2[j-1]));}}if(dp[length1][length2] <= 2)cout<<"YES"<<endl;elsecout<<"NO"<<endl; }return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。