【算法】最长公共子序列 递归 输出结果 优化

主要是如何输出结果的字符串,而不是简单的最长的公共序列的长度。

  1. 这里的1+LCS(...)表示每次在数值上累加!
  2. 这里的比较max(value1, value2)表示对数值上的大小进行比较!

  1. 这里的s1[i]+LCS(...)表示在字符串上的累加!
  2. 这里对len(str1)和len(str2) 是对str1和str2的(结果字符串)的长度进行比较

因为上面的递归 会导致重复的计算

所以通过记录路径 来优化时间 该memo用来记录递归路上的 所有存下的best match string

def LCS(i, j, s1, s2, memo):
    if i >= len(s1) or j >= len(s2):
        return ""
    if s1[i] == s2[j]:
        if memo[i+1][j+1] == "":   #如果两个字符相同
            memo[i+1][j+1] = LCS(i+1, j+1, s1, s2, memo)
        memo[i][j] = s1[i]+memo[i+1][j+1]
        return s1[i]+LCS(i+1, j+1, s1, s2, memo)
    else:
        str1 = memo[i][j+1]
        str2 = memo[i+1][j]
        if memo[i][j+1] == "":
            str1 = LCS(i, j+1, s1, s2, memo)
        if memo[i+1][j] == "":
            str2 = LCS(i+1, j, s1, s2, memo)
        if len(str1) > len(str2):
            memo[i][j] = str1
            return str1
        else:
            memo[i][j] = str2
            return str2

def lcs(s1, s2):
    memo = [["" for j in range(len(s2)+1)] for i in range(len(s1)+1)]
    value = LCS(0, 0, s1, s2, memo)
    print(memo)
    return value

s1 = "Look at me, I can fly!"
s2 = "Look at that, it's a fly"
print(lcs(s1, s2))

这样写有一个bug,就是

s1 = "abcdefghijklmnopqrstuvwxyz"
s2 = "ABCDEFGHIJKLMNOPQRSTUVWXYS"
print(lcs(s1, s2))

的结果是跑不出来的。

但是

s1 = "abc"
s2 = "ABC"
print(lcs(s1, s2))

是能跑出来的。

所以代码的逻辑并没有问题。

其实并不是跑不出来,只是跑的太慢了 = 优化没有起到作用。

这个的原因是,我在前面的代码中初始化为“”。如果确实是没有公共部分的时候,也为“”,所以memo的初始情况两个字符串没有公共部分,这两个点弄混淆了,继而可以更改使初始化为0,与没公共部分的“”区别开来。

def LCS(i, j, s1, s2, memo):
    if i >= len(s1) or j >= len(s2):
        return ''
    if s1[i] == s2[j]:
        if memo[i+1][j+1] == 0:   #如果两个字符相同
            memo[i+1][j+1] = LCS(i+1, j+1, s1, s2, memo)
        memo[i][j] = s1[i]+memo[i+1][j+1]
        return memo[i][j]
    else:
        str1 = memo[i][j+1]
        str2 = memo[i+1][j]
        if memo[i][j+1] == 0:
            str1 = LCS(i, j+1, s1, s2, memo)
        if memo[i+1][j] == 0:
            str2 = LCS(i+1, j, s1, s2, memo)
        if len(str1) > len(str2):
            memo[i][j] = str1
            return str1
        else:
            memo[i][j] = str2
            return str2

def lcs(s1, s2):
    memo = [[0 for j in range(len(s2)+1)] for i in range(len(s1)+1)]
    value = LCS(0, 0, s1, s2, memo)
    print(memo)
    return value

s1 = "Look at me, I can fly!"
s2 = "Look at that, it's a fly"
print(lcs(s1, s2))

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值