蓝桥杯试题:字符串转换---lanqiaoOJ 1507

题目:

设A和B是两个字符串。我们要用最少的字符操作次数,将字符串A转换为字符串B。这里所说的字符操作共有三种: 

1. 删除一个字符; 
2. 插入一个字符; 
3. 将一个字符改为另一个字符。 
对任给的两个字符串A和B,计算出将字符串A变换为字符串B所用的最少字符操作次数。

Input

第一行为字符串A;第二行为字符串B;字符串A和B的长度均小于200。

Output

只有一个正整数,为最少字符操作次数。

Sample Input

abcf

bcfe

Sample Output

2

 一开始拿到题没有思路的话举个例子就知道了,下图为dp[][]的转换过程,th(替换),sa(相同),de(删除),当然转换方法不止一种,例如当j(列)=3,i(行)=1时:两者(car和a)相互转换可以将r和c删除(两步),而删除c的步骤在转换i=0(空),j=1(c)时我们就早已知道要删除c,所以dp[1][0]=1。这也就是动态规划前一步为后一步服务的思想,由此我们可以推断出dp[i][j]的含义为:使A的第i个元素和B的第j个元素相同时所需要的最小步骤。若觉得理解不深刻可自行举两个简单的例子。

再看表格,当A串和B串第i,j个字母相同时(注意,此时A串和B串前面的字母一定相同,因为这就像多米诺骨牌一样,我们已经使得前面的骨牌倒下,并计算出了最小步骤。)我们直接取两者的前一步dp[i-1][j-1]即可

其他情况,dp[i][j] = min(dp[i-1][j], dp[i - 1][j - 1] dp[i][j-1])+1(蓝桥杯官方写法),为什么是取这三个方向呢,对照表格可以看到dp[i-1][j]相当于将”atn“删除一个字符以求得和A串相等;dp[i - 1][j - 1]相当于前面都相同,唯有这个不同,所以要修改;dp[i][j-1]相当于将”cartoon“删除一个字符以求得和A串相等;

(我感觉这个可以再优化,或许只需dp[i][j]=dp[i - 1][j - 1] +1即可,我举了两个例子是对的,或许有反例)

有些箭头没标

可运行代码如下(这也是蓝桥杯官方写法): 

def transStrMinStep(A,B):
    A_len=len(A)-1 #列
    B_len=len(B)-1
    dp=[[0 for _ in range(B_len+1)] for _ in range(A_len+1)]
    for i in range(1,A_len+1): #行,从1赋值是因为dp[0][0]已经初始化成0,没必要再初始化了
        dp[i][0]=i
    for j in range(1,B_len+1): #列
        dp[0][j]=j
    for i in range(1,A_len+1):
        for j in range(1,B_len+1):
            if A[i] != B[j]:
                dp[i][j]=(min(dp[i-1][j-1],dp[i-1][j],dp[i][j-1])+1)
            if A[i] == B[j]:
                dp[i][j] = dp[i - 1][j - 1]
    return dp[-1][-1]
A=input()
B=input()
A=''+A
B=''+B
print(transStrMinStep(A, B))

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值