在 coursera 上学习了生物信息学课程。有一个我无法解决的问题。关键是我们有两个变量:
- 包含重复字母组合的长单词中的字母列表(例如 ACGTTGCATGTCGCATGATGCATGAGAGCT 和 CATG GCAT)
- 一个数字,指定重复字母的数量(在上面的示例中,给出了一个数字
我们需要找出哪些组合是最重复的。我找到了一个解决方案,但无法理解一行:
Count = CountDict(Text, k)我抛出一个错误,据我所知,它的含义是创建字典。
# Input: A string Text and an integer k # Output: A list containing all most frequent k-mers in Text def FrequentWords(Text, k): FrequentPatterns = [] Count = CountDict(Text, k) m = max(Count.values()) for i in Count: if Count[i] == m: FrequentPatterns.append(Text[i:i+k] FrequentPatternsNoDuplicates = remove_duplicates(FrequentPatterns) return FrequentPatternsNoDuplicates
我认为生物信息学意味着一个有效的解决方案,因为。基因组字符串可能很长。
而一种有效的解决方案,尤其是对于大k,在这种情况下是使用一个后缀数组结合确定两个相邻后缀(LCP)的最大公共前缀。通过简单的方式构建后缀数组具有复杂性
O(NlogN)或O(Nlog^2(N)). 还有一些算法更难在线性时间内实现。编辑:
在代码中注释掉了一个带有错误渐近的简短 Python 实现。从这里
替换为 Manber-Myers 算法的实现(渐近线应该是 O (NlogN),但是,据我了解,该实现不为任意输入数据提供此功能)
LCP 是在线性时间中构建的——我给出了一个高效且简单的 Kasai 算法。
构建完LCP后,需要从中分离出最长的序列,所有的元素都不小于给定的长度k(我认为这是在Python中的一行完成的)。时间是线性的。
最大序列的长度对应于(更准确地说,减一)所需长度的最频繁子串的重复次数。要获取此子字符串本身,您需要从后缀数组的相应元素的索引开始获取一个子字符串。
后缀数组输出和 lcp:
在 lcp 中,我们看到两个长度为 2 的块(意味着两个子字符串出现 3 次),其值 >=4:
5, 4 и 6, 5从位置 8 和 17 开始。后缀数组中的这些位置包含原始字符串 20 和 19 中的索引,它们对应于子字符串CATG和GCAT一个简单直接的算法:计算每个长度为 [重叠] 子串的出现次数
k,然后输出重复次数最多的子串:尝试类似:
另一种选择(我发现很难估计算法的复杂性):