【问题标题】:python recursion with bubble sortpython递归与冒泡排序
【发布时间】:2013-12-02 04:39:07
【问题描述】:

所以,我有这个问题,我收到 2 串字母 ACGT,一个只有字母,另一个包含字母和破折号“-”。两者的长度相同。带有破折号的字符串与没有破折号的字符串进行比较。一个细胞一个细胞。对于每对配对,我都有一个评分系统。我为评分系统编写了这段代码: 例如: dna1:-ACA dna2:TACG 得分为-1。 (因为破折号与字母(T)相比给出-2,字母与相同字母相比给出+1(A到A),+1(C到C)和不相似的字母给出(-1)所以总和是-1。

def get_score(dna1, dna2, match=1, mismatch=-1, gap=-2):
""""""

score = 0

for index in range(len(dna1)):
    if dna1[index] is dna2[index]:
        score += match
    elif dna1[index] is not dna2[index]:
        if "-" not in (dna1[index], dna2[index]):
            score += mismatch
        else:
            score += gap

这工作正常。

现在我必须使用递归来为 2 个字符串提供最好的分数。 我收到 2 个字符串,这次它们可以是不同的大小。 (我不能改变字母的顺序)。 所以我编写了这段代码,将“-”添加到较短的字符串中,以创建 2 个相同长度的字符串并将它们放在列表的开头。现在我想开始移动破折号并记录每个破折号位置的分数,最后获得最高的可能分数。所以为了移动破折号,我写了一个小气泡排序..但它似乎没有做我想要的。我意识到这是一个很长的问题,但我希望得到一些帮助。如果我写的任何内容不明白,请告诉我。

def best_score(dna1, dna2, match=1, mismatch=-1, gap=-2,\
                         score=[], count=0):
""""""

diff = abs(len(dna1) - len(dna2))

if len(dna1) is len(dna2):
    short = []
elif len(dna1) < len(dna2):
    short = [base for base in iter(dna1)]
else:
    short = [base for base in iter(dna2)]

for i in range(diff):
    short.insert(count, "-")

for i in range(diff+count, len(short)-1):
    if len(dna1) < len(dna2):
        score.append((get_score(short, dna2),\
                      ''.join(short), dna2))
    else:
        score.append((get_score(dna1, short),\
                      dna1, ''.join(short)))
    short[i+1], short[i] = short[i], short[i+1]

if count is min(len(dna1), len(dna2)):
    return score[score.index(max(score))]
return best_score(dna1, dna2, 1, -1, -2, score, count+1)

【问题讨论】:

  • 澄清一下,您似乎正在尝试找到可能的最佳位置(定义为最高分)将短划线序列插入较短的 DNA 字符串中,其中所有短划线都相邻?
  • 破折号由我插入,以防 1 个字符串比另一个短。所以基本上你是对的,我需要找到破折号的最佳位置以获得最高分。我想如果我把它们放在开头,我可以通过冒泡排序移动每一步最右边的破折号直到结束,然后重置破折号并将它们向前移动 1 个单元格并重复该过程。这样我就记录了所有可能的分数并返回最高的分数。如果字符串大小相同,我不必插入破折号。这种情况可以用第一个函数解决,因为它只有 1 个可能的分数。没有任何动作。
  • 例如:TCAATTAGCTT', 'TATA' 是两个字符串。我将破折号向右插入,直到其长度相同,然后根据规则在正确的字符串内移动它们以获得最佳分数。我不能改变字母的顺序。
  • 你能用破折号分割你的小字符串吗?即T-A-T-A----
  • 是的,只要总长度等于另一个字符串并且我不改变字母顺序。我可以用破折号做任何我想做的事情来产生最高分

标签: python recursion bubble-sort


【解决方案1】:

首先,如果我正确解读了您的成本函数,则您的最佳分值不取决于差距,因为破折号的数量是固定的。

其次,它是线性依赖于不匹配的数量,因此不依赖于匹配和不匹配的精确值,只要它们分别是正数和负数。

所以你的任务简化为查找最长字符串字母的最长子序列,严格匹配最短字母的子序列。

第三,由M(string, substr)函数定义从上面返回的最佳匹配长度。如果你最小的字符串第一个字母是S,也就是substr == 'S&lt;letters&gt;',那么

M(string, 'S<letters>') = \
    max(1 + M(string[string.index(S):], '<letters>') + # found S
            M(string[1:], '<letters>')) # letter S not found, placed at 1st place

后者是一个易于实现的递归表达式。

对于一对string, substr 表示m=M(string, substr) 最好的分数相等

m * match + (len(substr) - m) * mismatch + (len(string)-len(substr)) * gap

很简单,将最大值存储在递归表达式中,以找到最佳匹配。

【讨论】:

  • alko 给你一个来自学校解决方案的例子:dna1: TAGCAAG dna2: TGGGCAAATTGAACCGGAAT。 >>>>>>> (-21, 'T-----A--G---C--AAG', 'TGGGCAAATTGAACCGGAAT') 是包含答案的输出元组。正如您所看到的,分数在元组的开头,然后他们添加了破折号以使字符串均匀,并且对于 -21 的最高分数,发现破折号应该按照那个确切的顺序。
  • @user2970357 你给它干什么?这种情况符合我的回答中写的内容
  • 我不确定我是否完全理解您的代码。例如,如果 dna1 是 TAGAGACAGC,而 dna2 是 AGCGACGCGAAGCGAGCGACCGAT。如果我没看错,它会寻找“T”,在最后找到它,然后剩下的字母必须放在后面?
  • @user2970357 that try 是max(...) 中的第一个表达式; second 表示将 T 放在第一位并且从第二个开始查找“A”的情况。
  • alko 这看起来不错,但我无法理解代码。想知道是否可以为像我这样的 Python 初学者以更用户友好的方式编写它
猜你喜欢
  • 2013-10-09
  • 2012-05-28
  • 1970-01-01
  • 2021-06-22
  • 2021-03-24
  • 2011-12-09
  • 2013-11-29
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多