[英]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.