Python: как считать перекрывающиеся вхождения подстроки

python

5521 просмотра

4 ответа

Я хотел посчитать, сколько раз строка типа «aa» появляется в «aaa» (или «aaaa»).

Самый очевидный код дает неправильный (или, по крайней мере, не интуитивный) ответ:

'aaa'.count('aa')
1 # should be 2
'aaaa'.count('aa')
2 # should be 3

У кого-нибудь есть простой способ это исправить?

Автор: nivk Источник Размещён: 13.11.2019 11:33

Ответы (4)


10 плюса

Из str.count()документации:

Возвращает количество неперекрывающихся вхождений подстроки sub в диапазоне [start, end]. Необязательные аргументы start и end интерпретируются как обозначения срезов.

Так что нет. Вы получаете ожидаемый результат.

Если вы хотите посчитать количество совпадающих совпадений, используйте regex:

>>> import re
>>> 
>>> len(re.findall(r'(a)(?=\1)', 'aaa'))
2

Это находит все вхождения a, за которыми следует a. Второй aне будет захвачены, так как мы использовали смотреть вперед, который является нулевой шириной утверждения.

Автор: Rohit Jain Размещён: 10.10.2013 05:39

6 плюса

haystack = "aaaa"
needle   = "aa"

matches  = sum(haystack[i:i+len(needle)] == needle 
               for i in xrange(len(haystack)-len(needle)+1))

# for Python 3 use range instead of xrange
Автор: kindall Размещён: 10.10.2013 05:42

1 плюс

Решение не учитывает дублирование.

Попробуй это:

big_string = "aaaa"
substring = "aaa"
count = 0 

for char in range(len(big_string)):
    count += big_string[char: char + len(subtring)] == substring

print count
Автор: Lucas Ribeiro Размещён: 10.10.2013 06:25

0 плюса

Вы должны быть осторожны, потому что вы, кажется, ищете непересекающиеся подстроки. Чтобы это исправить я бы сделал:

len([s.start() for s in re.finditer('(?=aa)', 'aaa')])

И если вас не волнует позиция, где начинается подстрока, вы можете сделать:

len([_ for s in re.finditer('(?=aa)', 'aaa')])

Хотя кто-то умнее меня может показать, что есть различия в производительности :)

Автор: mlnyc Размещён: 10.10.2013 05:44
Вопросы из категории :
32x32