【问题标题】:Efficient Way to Count K-mers in O(k*N + k*Q)?在 O(k*N + k*Q) 中计算 K-mer 的有效方法?
【发布时间】:2019-09-10 00:15:15
【问题描述】:

我有一串小写字母。我需要找出问题提出的每个 k-mer 出现了多少次。问题是我需要按问题要求的 k-mers 顺序输出计数。另一个问题是我可能需要多次输出同一个 k-mer 的计数。我需要在 O(kN +kQ) 中完成此操作,其中 k 是 k-mer 的长度,N 是 DNA 字符串的长度,Q 是特定 k-mer 的数量兴趣。

例如,对于以下输入,其中 N=7,k=2,q=3,aaabaab 是 DNA 字符串,接下来的 5 行是我感兴趣的 k-mers:

7 3 5
aaabaab
aaa
aab
aaa
baa
xyz

我希望输出以下内容:

aaa 1
aab 2
aaa 1
baa 1
xyz 0

请注意,aaa 被询问了两次!

我有一个 Q k-mers 列表。我有一本带有计数的 k-mers 字典(字典的长度可能小于 Q)。使用 for 循环,我遍历 DNA 和每个字符,同时跟踪当前的 k-mer O(N)。在下一次迭代中,我通过删除第一个字母并附加当前字符来更新当前的 k-mer。为了输出答案,我迭代了 Q k-mers 列表并在字典中搜索它的计数。

l, n , k, q = [int(x) for x in sys.stdin.readline().strip('\n').split(' ')]

dna = ''

for i in range(l):
    dna += sys.stdin.readline().strip('\n')

mykmer =[]
mycount = {}

for i in range(q):
    kmer = sys.stdin.readline().strip('\n')
    mykmer.append(kmer)   
    mycount[kmer]=0


current = dna[0:k]

for j in range(k-1,len(dna)): 

    if j != k-1:
        current = current[1:]+str(dna[j]) 

    if current in mykmer:
        mycount[current] += 1



for x in mykmer:
    print(str(x)+' '+str(mycount[x]))

我得到了正确的答案,但我超时了!

【问题讨论】:

  • “超时”?如果您要解决此类界面的问题,我们需要您引用原始来源。
  • 欢迎来到 StackOverflow。请按照您创建此帐户时的建议阅读并遵循帮助文档中的发布指南。 Minimal, complete, verifiable example 适用于此。在您发布 MCVE 代码并准确说明问题之前,我们无法有效地帮助您。您的帖子超过一半的输入开销与手头的问题无关。

标签: python algorithm data-structures


【解决方案1】:

我会将您的内部循环改进为:

for j in range(len(dna) - (len(dna) % k)):
    current = dna[j:j+k]
    if current in mycount:
        mycount[current] += 1

切片一次的成本低于重复切片和追加。 current = current[1:]+str(dna[j]) 的成本高于 dna[j:j+k]。因为它导致 3 个字符串分配,而切片导致一个。

使用您已有的字典而不是列表来进行成员资格测试。这消除了 Q 因子。

range(len(dna) - (len(dna) % k)) 确保循环不会不必要地考虑最后几个索引。

【讨论】:

  • 谢谢!我喜欢 len(dna)%k。 :)
猜你喜欢
  • 2010-11-04
  • 1970-01-01
  • 1970-01-01
  • 2020-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-21
相关资源
最近更新 更多