簡體   English   中英

如何打印使用動態編程找到的子序列

[英]How to print the subsequence found using dynamic programming

我已經編寫了計算最長回文序列的代碼。

def longest_pal_subseq(sequence, i, j):
    if (i == j): 
        return 1
    if (sequence[i] == sequence[j] and j - i == 1): 
        return 2
    if (sequence[i] == sequence[j]): 
        return longest_pal_subseq(sequence, i + 1, j - 1) + 2
    return max(longest_pal_subseq(sequence, i, j - 1),  
               longest_pal_subseq(sequence, i + 1, j)) 

if __name__ == '__main__': 
    sequence = "abracadabra"
    print("Length: ", longest_pal_subseq(sequence, 0, len(sequence)  - 1))

但是,如何修改代碼以打印它發現的那個長度的子序列呢?

編輯:原始答案有一個錯誤。
這是最快,最容易遵循的方法,但是不使用動態編程。 它僅返回不符合問題要求的連續回文。

def is_pal(string):
    return string == string[:: -1]

def longest_pal(string):
    full = len(string)
    for length in range(full, -1, -1):
        for i in range(full-length+1):
            if is_pal(string[i:length+i]):
                return length, i, string[i:length+i]

longest_pal('abracadabra')
# (3, 3, 'aca')

我可以看到2個長度為3'aca'和'ada'的回文,但長度都不為7。

第二種方法使用字典res_so_far存儲具有最長回文子序列的序列。 如果對同一序列的處理不止一次,則結果將從字典返回,而不運行其余的遞歸函數調用。 這將返回基本序列中不連續的回文序列。

def longest(a, b):
        if len(a) >= len(b): return a
        return b


def longest_pal_in( sequence ):

    res_so_far = {}  # To store intermediate results as they are found.
    def set(seq, res):
        """ set result so far then return result. 
            This is incorporated in each return statement in longest_pal 
        """
        res_so_far[seq] = res
        return res

    def longest_pal( sequence ):
        try:
            return res_so_far[sequence]
            # If sequence is stored in res_so_far return the result
        except KeyError: # If not run the rest of the function
            pass

        if len( sequence ) < 4:
            if sequence[0] == sequence[-1]:  # len 1,2, or 3 if first == last then palindrome
                return set(sequence, sequence)
        elif sequence[0] == sequence[-1]:
            # Changed to find sub sequences, not substrings        
            return set(sequence, sequence[0]+longest_pal( sequence[1:-1] )+sequence[-1] )
            # Three lines below removed to return non contiguous sub sequences.
            # sub = longest_pal( sequence[1:-1] )
            # if len(sub) == (len(sequence) - 2):
            #     return set(sequence, sequence)
        return set(sequence, longest(longest_pal( sequence[:-1] ), longest_pal( sequence[1:] )))

    return longest_pal(sequence)

時機

test = 'abracadabra'

%timeit longest_pal(test)  # Not recursive
# 54.4 µs ± 765 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit longest_pal_in(test)  # Recursive
# 93.5 µs ± 2.95 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%timeit longest_pal_in(test+test)
# 369 µs ± 5.62 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit longest_pal_in(test+test+test)
# 784 µs ± 39.8 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

longest_pal_in大致執行O(n ^ 2)

高溫超導

您可以返回具有回文和長度的字典。

return {"length": max(longest_pal_subseq(sequence, i, j - 1),  
           longest_pal_subseq(sequence, i + 1, j)),
        "palindrome": sequence}

您還必須更改longest_pal_subseq才能使用字典。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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