簡體   English   中英

如何編寫一個函數來使用動態規划找到最長公共子序列?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM