如何使用递归来查找最长的有效DNA序列?

时间:2019-04-22 19:51:02

标签: python

我是Python的新手,我有一个我无法理解的项目。当给定两条链时,它需要使用递归来找到最长的有效DNA序列。我得到了一个名为dna.txt的文件。文件的第一行包含一个数字,表示将有多少对DNA链。然后其余的行就是DNA字符串。我的工作是分别查看每对链,找到最长的有效DNA序列,并将其写入名为dnaresults.txt的新文件中。如果要通过迭代完成此操作,我很有信心可以处理。但是该项目要求我使用递归来a)查找有效的DNA序列,b)查找最长的DNA对。我了解递归的基本知识(斐波那契,总和等),但是我无法解决这种情况下如何应用递归。

例如,输入文件如下所示:

fun remove_element (elemlist:int list, elem:int) = 
  case elemlist of
  [] => []
  | head::tail => if elem = head
                  then remove_element (tail, elem)
                  else head::remove_element (tail, elem)

并且我需要将其输出到新文件:

3
GAAGCTCG
CCTCGGGA
AAATTT
GGGCCC
CTCTAGGAC
GAGTACCTG

这是我到目前为止尝试过的。我可以使用该数字来确定执行循环的次数。我可以将成对的线分开并使用自己的变量。但是一旦需要评估和比较它们,我就很困惑,因为在这种情况下我不知道如何使用递归。

DNA sequence pair 0:
AGC
TCG

DNA sequence pair 1:
No matches found

DNA sequence pair 2:
GGAC
CCTG

所以这就是我现在所在的位置。如果有人可以通过递归指向我正确的方向,那将是惊人的。对于要如何使用递归来比较DNA链,同时也只存储和返回最长的链,我真的是一无所知。预先感谢!

编辑:抱歉。当一条链上的A与另一条链上的T配对(反之亦然),而一条链上的G与另一条链上的C配对(反之亦然)时,DNA序列有效。

def main():
    dnaFile = open('dna.txt').readlines()
    numOfPairs = int(dnaFile[0])

    for i in range(0, numOfPairs*2, 2):
        firstStrand = str(dnaFile[i+1])
        secondStrand = str(dnaFile[i+2])
        firstStrand.upper()
        secondStrand.upper()

这是一个有效的序列,因为每一对都是A-T或G-C。

ACTGTC
TGACAG

这不是一个完全有效的序列,因为并非每一对都是A-T或G-C。只有第三对和第四对有效(TG和AC)。

1 个答案:

答案 0 :(得分:1)

这种类型的问题的递归使用愚蠢的堆栈,并且比使用占用线性时间和恒定空间的内置数据结构慢得多。我知道需要递归,因为这是您的问题,但我仍然觉得我应该这样说。

这是一个递归解决方案:

第一个用于检查有效对的函数:

def valid_pair(c1, c2):
    pairs = {
      'G': 'C',
      'C': 'G',
      'A': 'T',
      'T': 'A'
    }
    return pairs[c1] == c2

现在是递归方法:

def compare_strands(s1, s2, count=0, result=["", ""]):
    if not s1 or not s2: # base case
        return count, result
    # If it is not a valid pair
    if not valid_pair(s1[0], s2[0]):
        old_max, old_str = count, result
        new_max, new_str = compare_strands(s1[1:], s2[1:], 0, ["", ""])
        if new_max < old_max:
            new_max = old_max
            new_str = old_str
    else:
        temp_result = []
        temp_result.append(result[0] + s1[0])
        temp_result.append(result[1] + s2[0])
        # result[1] += s2[0]
        count = count + 1
        new_max, new_str = compare_strands(s1[1:], s2[1:], count, temp_result)
    return new_max, new_str

测试:

with open('dna.txt', 'r') as f:
    size = int(f.readline())
    for i in range(size):
        strand1 = f.readline().strip('\n')
        strand2 = f.readline().strip('\n')
        print(compare_strands(strand1, strand2))

输出:

(3, ['AGC', 'TCG'])
(0, ['', ''])
(4, ['GGAC', 'CCTG'])

编辑::要写入文件。

with open('dna.txt', 'r') as f:
    size = int(f.readline())
    for i in range(size):
        strand1 = f.readline().strip('\n')
        strand2 = f.readline().strip('\n')
        result = compare_strands(strand1, strand2)
        with open('result.txt', 'a') as result_file:
            result_file.write('DNA sequece pair {}:\n'.format(i))
            if result[0]:
                result_file.write('{}\n{}\n\n'.format(result[1][0], result[1][1]))
            else:
                result_file.write('No matches found\n\n')