华为机试---动态规划---优化编辑器问题

版权声明:本文为CSDN博主「wskyp」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u014226012/article/details/65937179

问题描述
Levenshtein 距离,又称编辑距离,指的是两个字符串之间,由一个转换成另一个所需的最少编辑操作次数。许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除一个字符。编辑距离的算法是首先由俄国科学家Levenshtein提出的,故又叫Levenshtein Distance。
Ex:
字符串A:abcdefg
字符串B: abcdef
通过增加或是删掉字符”g”的方式达到目的。这两种方案都需要一次操作。把这个操作所需要的次数定义为两个字符串的距离。
要求:
给定任意两个字符串,写出一个算法计算它们的编辑距离。

解题思路
问题抽象:将A变为B所需的最少操作步数(也可以是B变为A的最少操作步数,两个角度一样。因为A变为B如果有插入的话,对应B变为A就可以等价为删除;A变为B为替换的话,B变为A也可等价位替换;A变为B为删除的话,B变为A等价为插入,因为步数都一样)。用dp[x][y]表示A的前x个字符转换为B的前y个字符所需要的最少操作步数
最优子结构:A的前x个字符变为B的前y个字符所需要的最少操作步数d[x][y]取决于子问题:

1)A的最后一位参与变换:
if(A的第x个字符不等于B的第y个字符)dp[x][y]=dp[x-1][y-1]+1 //将A的前x-1个字符变为B的前y-1个字符, 然后将最后一个字符替换成B的最后一个字符(一步)
else dp[x][y]=dp[x-1][y-1] //如果A的最后一个字符等于B的最后一个字符,则A的前x个字符变为B的前y个字符等价于将A的前x-1个字符变为B的前y-1个字符
2)A的最后一位不参与变换(删除掉A的最后一位)
dp[x][y]=dp[x-1][y]+1 //将A的前x-1个字符变为B,然后将最后一个字符删除
3)B的最后一位不参与变化(删除掉B的最后一位)
dp[x][y]=dp[x][y-1]+1 //将B的前y-1个字符变为A,然后将最后一个字符删除

dp[x][y]=min{dp[x-1][y-1]+1或dp[x-1][y-1],dp[x-1][y]+1,dp[x][y-1]+1}

当x=0时,即A为空字符串,则A变为B的前Y个字符所需的操作为y,dp[0][y]=y;
同理,y=0时,dp[x][0]=x;
这样自底向上就能求出将A变为B最少的操作步数dp[a.length][b.length].

动态规划的关键一步就是如何就将问题与子问题联系起来,即将问题i想办法用问题i-1表示

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
#define mp make_pair
#define pb push_back
#define fi first
#define se second

int dp[1005][1005];

int main()
{
    string s1,s2;
    while(cin >> s1 >> s2){
        int len1 = s1.size();
        int len2 = s2.size();
        memset(dp,inf,sizeof(dp));
        for(int i = 0;i <= len1;++i){
            dp[i][0] = i;
        }
        for(int i = 0;i <= len2;++i){
            dp[0][i] = i;
        }
        for(int i = 1;i <= len1;++i){
            for(int j = 1;j <= len2;++j){
                if(s1[i - 1] != s2[j - 1]){
                    dp[i][j] = min(dp[i][j],dp[i - 1][j - 1] + 1);
                }else{
                    dp[i][j] = min(dp[i][j],dp[i - 1][j - 1]);
                }
                dp[i][j] = min(dp[i][j],dp[i - 1][j] + 1);
                dp[i][j] = min(dp[i][j],dp[i][j - 1] + 1);
            }
        }
        cout << dp[len1][len2] << endl;
    }
    return 0;
}
发布了269 篇原创文章 · 获赞 33 · 访问量 8万+

猜你喜欢

转载自blog.csdn.net/qq_36386435/article/details/100573728