簡體   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