我想找到字符串中子字符串的所有计数(重叠和非重叠)。 我找到了两个答案,其中一个是使用正则表达式,这不是我的意图,另一个比我需要的效率更高。 我需要这样的东西:
'ababaa'.count('aba') == 2
str.count()
只计算简单的子串。我该怎么办?
答案 0 :(得分:3)
def sliding(a, n):
return (a[i:i+n] for i in xrange(len(a) - n + 1))
def substring_count(a, b):
return sum(s == b for s in sliding(a, len(b)))
assert list(sliding('abcde', 3)) == ['abc', 'bcd', 'cde']
assert substring_count('ababaa', 'aba') == 2
答案 1 :(得分:1)
这可以解决这个问题吗?
def count(string, substring):
n = len(substring)
cnt = 0
for i in range(len(string) - n):
if string[i:i+n] == substring:
cnt += 1
return cnt
print count('ababaa', 'aba') # 2
我不知道是否有更有效的解决方案,但这应该有用。
答案 2 :(得分:1)
在这里,使用re.finditer()是实现目标的最佳方式。
import re
def get_substring_count(s, sub_s):
return sum(1 for m in re.finditer('(?=%s)' % sub_s, s))
get_substring_count('ababaa', 'aba')
# 2 as response
答案 3 :(得分:1)
count = len(set([string.find('aba',x) for x in range(len(string)) if string.find('aba',x) >= 0]))
答案 4 :(得分:1)
这是您可以使用的功能:
def count(haystack, needle):
return len([x for x in [haystack[i:j+1] for i in xrange(len(haystack)) for j in xrange(i,len(haystack))] if x == needle])
然后:
>>> count("ababaa", "aba")
2
答案 5 :(得分:1)
遍历切成薄片的字符串
def count_substring(string, sub_string):
l = len(sub_string)
n = len(string)
count = sum(1 for i in range(n-l+1) if string[i:i+l].count(sub_string)>0 )
return count
答案 6 :(得分:0)
蛮力方法就是
n = len(needle)
count = sum(haystack[i:i+n] == needle for i in range(len(haystack)-n+1))
(这是有效的,因为在Python中True
和False
相当于数字1
和0
,用于大多数用途,包括数学)。
使用正则表达式可能是
count = len(re.findall(needle[:1]+"(?="+re.escape(needle[1:])+")",
haystack))
(即使用a(?=ba)
代替aba
来查找重叠匹配)
答案 7 :(得分:0)
要考虑的另一种方法是利用Counter容器。尽管对于较短的字符串,最快的答案是最快的,但如果您要在较长的字符串中搜索相对较短的子字符串,则Counter方法将占据优势。另外,如果您需要重构它以对同一主字符串执行多个子字符串计数查询,那么Counter方法将开始看起来更具吸引力
例如,搜索一个长度= 3的子字符串,使用timeit得到了以下结果;
主字符串长度/可接受的答案/应对方法
6个字符/ 4.1us / 7.4us
50个字符/ 24.4us / 25us
150个字符/ 70.7us / 64.9us
1500个字符/ 723us / 614us
from collections import Counter
def count_w_overlap(search_string, main_string):
#Split up main_string into all possible overlap possibilities
search_len = len(search_string)
candidates = [main_string[i:i+search_len] for i in range(0, len(main_string) - search_len + 1)]
#Create the Counter container
freq_count = Counter(candidates)
return freq_count[search_string]