上述问题的解决方法是使用动态规划来找出两个DNA字符串的最长公共子序列(LCS)。
https://rosalind.info/problems/lcsq/
很经典的动态规划问题了。直接给出解题步骤:
1. 初始化矩阵:创建一个大小为 (len(s) + 1) x (len(t) + 1) 的矩阵。将第一行和第一列的元素初始化为零。这些代表了一个字符串与空字符串的LCS,其长度为零
2.?填充矩阵:对于矩阵中的每个元素 (i, j)(不包括第一行和第一列),检查字符 s[i-1] 和 t[j-1] 是否相等。
下面上图来解释这个动态的过程:
3.?回溯找出LCS:从矩阵的右下角单元格 (len(s), len(t)) 开始回溯以重构LCS。
4.?重构LCS:在回溯过程中收集的字符(逆序排列)形成了LCS。
给定输入:给定两个最大长度为1kbp的DNA字符串s和t(以FASTA格式表示)。
输出:s和t的一个最长公共子序列。如果存在多个解决方案,你可以返回任何一个。
from method import fasta
namelist,valuelist = fasta("")
s = valuelist[0]
t = valuelist[1]
def lcs(s, t):
# 创建一个动态规划矩阵
dp = [[0] * (len(t) + 1) for _ in range(len(s) + 1)]
# 填充矩阵
for i in range(1, len(s) + 1):
for j in range(1, len(t) + 1):
if s[i - 1] == t[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
# 回溯找出LCS
i, j = len(s), len(t)
lcs = []
while i > 0 and j > 0:
if s[i - 1] == t[j - 1]:
lcs.append(s[i - 1])
i -= 1
j -= 1
elif dp[i - 1][j] > dp[i][j - 1]:
i -= 1
else:
j -= 1
# LCS是逆序构建的
return ''.join(reversed(lcs))
print(lcs(s, t))