Rosalind 033 Finding a Shared Spliced Motif
2023-12-29 07:05:44
题目背景:
上述问题的解决方法是使用动态规划来找出两个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] 是否相等。
- 如果相等,该单元格的值为左上角对角线单元格 (i-1, j-1) 的值加1。
- 如果不相等,取其正上方 (i-1, j) 或左侧 (i, j-1) 单元格中的最大值。
下面上图来解释这个动态的过程:
3.?回溯找出LCS:从矩阵的右下角单元格 (len(s), len(t)) 开始回溯以重构LCS。
- 如果 s[i-1] 等于 t[j-1],则该字符是LCS的一部分。向左上对角线移动,并将此字符添加到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))
文章来源:https://blog.csdn.net/weixin_45848873/article/details/135279054
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!