繁体   English   中英

有没有比 count() 更快的方法来计算字符串中的非重叠出现?

[英]Is there a faster way to count non-overlapping occurrences in a string than count()?

给定一个最小长度 N 和一个 1 和 0 的字符串 S(例如“01000100”),我试图返回一个包含所有 '0' 的长度为 n 的子字符串的非重叠出现次数。 例如,给定 n=2 和字符串“01000100”,不重叠的“00”的数量为 2。

这就是我所做的:

def myfunc(S,N):
  return S.count('0'*N)

我的问题:有没有更快的方法来处理很长的字符串? 这是来自在线编码练习网站,我的代码通过了除一个测试用例之外的所有测试用例,由于无法在时间限制内完成而失败。 做一些研究似乎我只能发现 count() 是最快的方法。

这可能会更快:

>>> s = "01000100"
>>> def my_count( a, n ) :
...     parts = a.split('1')
...     return sum( len(p)//n for p in parts )
... 
>>> my_count(s, 2)
2
>>> 

count()的最坏情况是 O(N^2),上面的 function 是严格线性的 O(N)。 以下是 O(N^2) 数来自的讨论: 对字符串 Python 进行计数操作的计算成本是多少?


此外,您可以始终手动执行此操作,而不使用split() ,只需遍历字符串,将计数器(一旦保存counter // n某处)重置为1并增加计数器0 这肯定会击败任何其他方法,因为严格来说是 O(N)。


最后,对于相对较大的n值(n > 10?),可能存在一个亚线性(或仍然是线性,但具有更小的常数)算法,该算法首先将a[n-1]0进行比较,然后继续回到开始。 很有可能,某处会有一个1 ,所以如果a[n-1]1 ,我们就不必分析字符串的开头——仅仅是因为那里没有办法容纳足够多的零。 假设我们在 position k找到1 ,下一个要比较的 position 将是a[k+n-1] ,再次回到字符串的开头。

这样我们可以在搜索过程中有效地跳过大部分字符串。

lenik 发布了一个非常好的回复,效果很好。 我还发现了另一种比 count() 更快的方法,我也会在这里发布。 它使用正则表达式库中的 findall() 方法:

import re
def my_count(a, n):
  return len(re.findall('0'*n, a))

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM