[英]How to write a function to find the longest common subsequence using dynamic programming?
明确地说,我正在寻找子序列本身而不是长度。 我已经编写了这个函数,它在大多数情况下都可以工作,但在某些情况下它不起作用。 我必须在没有任何循环或导入的情况下递归地编写它。 我使用了 memoise 功能来提高效率,但这里没有包含它。
此函数在 s1 = "abcde" 和 s2 = "qbxxd"(正确返回 "bd")时起作用,但在 s1 = "看着我,我会飞!" 时不起作用。 和 s2 = “看那个,这是一只苍蝇”,它应该返回“看,一只苍蝇”,但我得到的是“看一只苍蝇”。 无论出于何种原因,逗号和空格都会被忽略。 我试过 s1 = "ab, cde" 和 s2 = "qbxx, d" 正确返回 "b, d"。
def lcs(s1, s2):
"""y5tgr"""
i = len(s1)
j = len(s2)
if i == 0 or j == 0:
return ""
if s1[i-1] == s2[j-1]:
return lcs(s1[:-1], s2[:-1]) + s1[i-1]
else:
return max(lcs(s1[:-1], s2), lcs(s1, s2[:-1]))
我感觉问题出在最后一行和 max 函数上。 我见过有 for 和 while 循环的解决方案,但不是没有。
只需稍作更改即可修复您的代码(您说得对,问题出在最大)。
只需更改 max 以便它使用它的 key 函数找到最大长度的字符串。
def lcs(s1, s2):
"""y5tgr"""
i = len(s1)
j = len(s2)
if i == 0 or j == 0:
return ""
if s1[i-1] == s2[j-1]:
return lcs(s1[:-1], s2[:-1]) + s1[i-1]
else:
# Find max based upon the string length
return max(lcs(s1[:-1], s2), lcs(s1, s2[:-1]), key=len)
但是,这在没有记忆的情况下非常慢
带有记忆功能的代码(以提高性能)
import functools
def memoize(obj):
cache = obj.cache = {}
@functools.wraps(obj)
def memoizer(*args, **kwargs):
if args not in cache:
cache[args] = obj(*args, **kwargs)
return cache[args]
return memoizer
@memoize
def lcs(s1, s2):
"""y5tgr"""
i = len(s1)
j = len(s2)
if i == 0 or j == 0:
return ""
if s1[i-1] == s2[j-1]:
return lcs(s1[:-1], s2[:-1]) + s1[i-1]
else:
return max(lcs(s1[:-1], s2), lcs(s1, s2[:-1]), key=len)
测试
s1 = "Look at me, I can fly!"
s2 = "Look at that, it's a fly"
print(lcs(s1, s2))
输出
Look at , a fly
对于字符串, max
取按字典序排在最后的字符串:
>>> max("a", "b")
'b'
>>> max("aaaaa", "b")
'b'
>>>
当然不是你需要的; 你似乎在寻找两者中较长的一个。 您不需要循环,只需比较:
lsc1 = lcs(s1[:-1], s2)
lcs2 = lcs(s1, s2[:-1])
return lcs1 if len(lcs1) > len(lcs2) else lcs2
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.