原字符串转目标字符串

本文介绍了一种通过插入、删除和替换操作将一个字符串转换成另一个字符串的算法,并提供了两种不同场景下的实现代码:一种考虑操作成本,另一种仅计算操作次数。

笔试遇到两次,整理一下。

第一次遇到(招银科技笔试)
题目:
让字符串s1转换为s2,有三种操作分别为插入ic,删除dc,改变rc,分别对应不同的费用,求转换字符串的最小费用
例子:
s1:“abc”
s2:“adc”
ic = 3
dc = 5
rc = 99
这时候先删除b然后插入d费用最小,为8.

思路:二维dp ,dp[i][j]表示从s1前i个字符调整到s2前j个字符的费用

代码

int main(){
    /*  让字符串s1转换为s2,有三种操作分别为插入ic,删除dc,改变rc,分别对应不同的费用,求转换字符串的最小费用*/
    string s1 = "abc";
    string s2 = "adc";
    int ic = 3;
    int dc = 5;
    int rc = 99;
    int len1 = s1.size();
    int len2 = s2.size();
    vector<vector<int>> dp(len1+1,vector<int>(len2+1));//dp[i][j]表示从s1前i个字符调整到s2前j个字符的费用

    //源字符串为空
    for(int i=1;i<=len2;i++){
        dp[0][i] = i*ic;
    }
    //目标字符串为空
    for(int j = 1;j<=len1;j++){
        dp[j][0] = j*dc;
    }
    for(int i=0;i<len1;i++){
        for(int j=0;j<len2;j++){
            if(s1[i] == s2[j]){
                dp[i+1][j+1] = dp[i][j];
            }else{
                dp[i+1][j+1] = min(min(dp[i+1][j] + ic,dp[i][j+1] + dc),dp[i][j]+rc);
                //dp[i+1][j] + ic对应了s1先删除一个到 再插入一个的费用
                //dp[i][j+1] + dc对应了s1先插入一个到 再删除一个的费用
                //dp[i][j]+rc 对应了直接改变一个字符的费用
            }

        }
    }
    cout << dp[len1][len2];
    return 0;
}

第二次遇到(小米笔试)
另一种简单版《原字符串转目标字符串》:
只考虑操作数,问要操作几次,相当于把前面的每种操作的cost变为1.
例子:
s1=“horse”
s2=“ros”
返回:3

int main(){
    /*  让字符串s1转换为s2,有三种操作分别为插入ic,删除dc,改变rc,分别对应不同的费用,求转换字符串的最小费用*/
    string s1 = "horse";
    string s2 = "ros";
    int len1 = s1.size();
    int len2 = s2.size();
    vector<vector<int>> dp(len1+1,vector<int>(len2+1));//dp[i][j]表示从s1前i个字符调整到s2前j个字符的费用

    //源字符串为空
    for(int i=1;i<=len2;i++){
        dp[0][i] = i;
    }
    //目标字符串为空
    for(int j = 1;j<=len1;j++){
        dp[j][0] = j;
    }
    for(int i=0;i<len1;i++){
        for(int j=0;j<len2;j++){
            if(s1[i] == s2[j]){
                dp[i+1][j+1] = dp[i][j];
            }else{
                dp[i+1][j+1] = min(min(dp[i+1][j] + 1,dp[i][j+1] + 1),dp[i][j]+1);
                //dp[i+1][j] + ic对应了s1先删除一个到 再插入一个
                //dp[i][j+1] + dc对应了s1先插入一个到 再删除一个
                //dp[i][j]+1对应了直接改变一个字符
            }

        }
    }

    cout << dp[len1][len2];
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值