使用递归在 Python 中查找最常见的长度为 k 的字符串

时间:2021-04-06 00:04:58

标签: python recursion

对于冗长的、可能漫无目的的解释,提前表示抱歉。 :)

我采用的方法,因为我专门从事 DNA 测序,是将每个碱基映射到一个数字,创建函数以在碱基和我分配给它们的值之间映射,然后创建一个数组为 k 个碱基 (4^k) 的每个组合设置一个槽,然后使用基本上充当滑动窗口的 for 循环,为每个 k 长度序列增加数组中的相应槽。然后,该算法在数组中搜索最大数,并使用数组中的索引找到最普遍的序列。

我目前收到以下错误:

Traceback (most recent call last):
  line 74, in <module>
    recFreqWords('ACGTTGCATGTCGCATGATGCATGAGAGCT', 4)
  line 65, in recFreqWords
    freqArray = computeFreqArray(text, k)
  line 59, in computeFreqArray
    freqArray[index] += 1
IndexError: list index out of range

原始代码如下:

def baseToOffset(base):
    if base == 'A':
        return 0
    if base == 'C':
        return 1
    if base == 'G':
        return 2
    if base == 'T':
        return 3

def offsetToBase(offset):
    if offset == 0:
        return 'A'
    if offset == 1:
        return 'C'
    if offset == 2:
        return 'G'
    if offset == 3:
        return 'T'

def patternToNumber(pattern):
    if len(pattern) == 0:
        return 0
    symbol = pattern[len(pattern)-2]
    print(symbol)
    prefix = pattern[:-1]
    print(prefix)
    offset = baseToOffset(symbol)
    print(offset)
    return (4 * patternToNumber(prefix) + offset)

def numberToPattern(index, k):
    if k == 1:
        return offsetToBase(index)
    else:
        prefixIndex = index // 4
        remainder = index % 4
        symbol = offsetToBase(remainder)
        prefixPattern = numberToPattern(prefixIndex, (k-1))
        return prefixPattern + symbol

def computeFreqArray(text, k):
    freqArray = [0] * (4**k)
    loopLimit = len(text) - k
    for i in range(0, loopLimit):
        pattern = text[i:(i+k+1)]
        index = patternToNumber(pattern)
        freqArray[index] += 1
    return freqArray

def recFreqWords(text, k):
    freqPatterns = []
    freqArray = computeFreqArray(text, k)
    maxCount = max(freqArray)
    loopLimit = (4**k) - 1
    for i in range(0, loopLimit):
        if freqArray[i] == maxCount:
            pattern = numberToPattern(i, k)
            freqPatterns.append(pattern)
    return freqPatterns

1 个答案:

答案 0 :(得分:2)

我认为你的问题可以归结为

collections.Counter(windows(dna, 4))

其中 windows 是您选择的函数,可能是像 How to implement a sliding window over the string in Python to have each new window constructed in O(1) 那样的高性能函数,或者可能是简单的函数

def windows(items, size):
    return (items[i:i + size] for i in range(len(items) - size))

例如

dna = 'ACGTTGCATGTCGCATGATGCATGAGAGCT'
collections.Counter(windows(dna, 4))

愿意

Counter({'GCAT': 3,
         'CATG': 3,
         'TGCA': 2,
         'ATGA': 2,
         'ACGT': 1,
         'CGTT': 1,
         'GTTG': 1,
         'TTGC': 1,
         'ATGT': 1,
         'TGTC': 1,
         'GTCG': 1,
         'TCGC': 1,
         'CGCA': 1,
         'TGAT': 1,
         'GATG': 1,
         'ATGC': 1,
         'TGAG': 1,
         'GAGA': 1,
         'AGAG': 1,
         'GAGC': 1})
相关问题