![](/img/trans.png)
[英]How to write a function to find the longest common subsequence using dynamic programming?
[英]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.