Подтвердить что ты не робот

Количество строк с перекрывающимися вхождениями

Каков наилучший способ подсчета количества вхождений данной строки, включая перекрытие в Python? Это самый очевидный способ:

def function(string, str_to_search_for):
      count = 0
      for x in xrange(len(string) - len(str_to_search_for) + 1):
           if string[x:x+len(str_to_search_for)] == str_to_search_for:
                count += 1
      return count


function('1011101111','11')
returns 5

?

Или есть лучший способ в Python?

4b9b3361

Ответ 1

Ну, это может быть быстрее, потому что это сравнение в C:

def occurrences(string, sub):
    count = start = 0
    while True:
        start = string.find(sub, start) + 1
        if start > 0:
            count+=1
        else:
            return count

Ответ 2

>>> import re
>>> text = '1011101111'
>>> len(re.findall('(?=11)', text))
5

Если вы не хотите загружать весь список совпадений в память, это никогда не будет проблемой! вы можете сделать это, если хотите:

>>> sum(1 for _ in re.finditer('(?=11)', text))
5

Как функция (re.escape, убедитесь, что подстрока не мешает регулярному выражению):

>>> def occurrences(text, sub):
        return len(re.findall('(?={0})'.format(re.escape(sub)), text))

>>> occurrences(text, '11')
5

Ответ 3

Вы также можете попробовать использовать новый модуль регулярного выражения Python, который поддерживает совпадающие совпадения.

import regex as re

def count_overlapping(text, search_for):
    return len(re.findall(search_for, text, overlapped=True))

count_overlapping('1011101111','11')  # 5

Ответ 4

Python str.count подсчитывает неперекрывающиеся подстроки:

In [3]: "ababa".count("aba")
Out[3]: 1

Вот несколько способов подсчета перекрывающихся последовательностей, я уверен, что их еще много:)

Регулярные выражения в режиме ожидания

Как найти совпадающие совпадения с регулярным выражением?

In [10]: re.findall("a(?=ba)", "ababa")
Out[10]: ['a', 'a']

Сгенерировать все подстроки

In [11]: data = "ababa"
In [17]: sum(1 for i in range(len(data)) if data.startswith("aba", i))
Out[17]: 2

Ответ 5

s = "bobobob"
sub = "bob"
ln = len(sub)
print(sum(sub == s[i:i+ln] for i in xrange(len(s)-(ln-1))))

Ответ 6

Как найти шаблон в другой строке с перекрытием

Эта функция (другое решение!) получает шаблон и текст. Возвращает список со всей подстрокой, расположенной в их и их положениях.

def occurrences(pattern, text):
    """
    input: search a pattern (regular expression) in a text
    returns: a list of substrings and their positions 
    """
    p = re.compile('(?=({0}))'.format(pattern))
    matches = re.finditer(p, text)
    return [(match.group(1), match.start()) for match in matches]

print (occurrences('ana', 'banana'))
print (occurrences('.ana', 'Banana-fana fo-fana'))

[('ana', 1), ('ana', 3)]
[('Bana', 0), ('nana', 2), ('fana', 7), ('fana', 15)]

Ответ 7

Мой ответ на вопрос bob о курсе:

s = 'azcbobobegghaklbob'
total = 0
for i in range(len(s)-2):
    if s[i:i+3] == 'bob':
        total += 1
print 'number of times bob occurs is: ', total

Ответ 8

def count_substring(string, sub_string):
    count = 0
    for pos in range(len(string)):
        if string[pos:].startswith(sub_string):
            count += 1
    return count

Это может быть самый простой способ.

Ответ 9

Вот мое решение edx MIT "find bob" * (* найти количество вхождений "bob" в строке с именем s), которая в основном подсчитывает перекрывающиеся вхождения данной подстанции:

s = 'azcbobobegghakl'
count = 0

while 'bob' in s:
    count += 1 
    s = s[(s.find('bob') + 2):]

print "Number of times bob occurs is: {}".format(count)

Ответ 10

Это можно решить с помощью регулярного выражения.

import re
def function(string, sub_string):
    match = re.findall('(?='+sub_string+')',string)
    return len(match)

Ответ 11

def count_substring(string, sub_string):
    counter = 0
    for i in range(len(string)):
        if string[i:].startswith(sub_string):
        counter = counter + 1
    return counter

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

Ответ 12

Довольно питоническим способом было бы использовать здесь понимание списков, хотя это, вероятно, было бы не самым эффективным.

sequence = 'abaaadcaaaa'
substr = 'aa'

counts = sum([
    sequence.startswith(sub, i) for i in range(len(sequence))
])
print(counts)  # 5

Список будет [False, False, True, False, False, False, True, True, False, False] как он проверяет все индексы в строке, и поскольку int(True) == 1, sum дает нам общее число из матчей.

Ответ 13

def count_overlaps (string, look_for):
    start   = 0
    matches = 0

    while True:
        start = string.find (look_for, start)
        if start < 0:
            break

        start   += 1
        matches += 1

    return matches

print count_overlaps ('abrabra', 'abra')

Ответ 14

Функция, которая принимает в качестве входных данных две строки и подсчитывает, сколько раз подстрока происходит в строке, включая перекрытия. Чтобы проверить, является ли sub подстрокой, я использовал оператор in.

def count_Occurrences(string, sub):
    count=0
    for i in range(0, len(string)-len(sub)+1):
        if sub in string[i:i+len(sub)]:
            count=count+1
    print 'Number of times sub occurs in string (including overlaps): ', count

Ответ 15

Для дублированного question я решил считать его 3 на 3 и сравнить строку, например.

counted = 0

for i in range(len(string)):

    if string[i*3:(i+1)*3] == 'xox':
       counted = counted +1

print counted

Ответ 16

Альтернатива, очень близкая к принятому ответу, но использующая while как тест if вместо включения if внутри цикла:

def countSubstr(string, sub):
    count = 0
    while sub in string:
        count += 1
        string = string[string.find(sub) + 1:]
    return count;

Это позволяет избежать while True: и, по моему мнению, немного чище

Ответ 17

Если строки велики, вы хотите использовать Rabin-Karp, вкратце:

  • текущее окно размера подстроки, перемещение по строке
  • хэш с O (1) служебными данными для добавления и удаления (т.е. перемещение на 1 char)
  • реализованный в C или полагающийся на pypy

Ответ 18

Это еще один пример использования str.find() но многие ответы делают его более сложным, чем необходимо:

def occurrences(text, sub):
    c, n = 0, text.find(sub)
    while n != -1:
        c += 1
        n = text.find(sub, n+1)
    return c

In []:
occurrences('1011101111', '11')

Out[]:
5

Ответ 19

Данный

sequence = '1011101111'
sub = "11"

Код

В этом конкретном случае:

sum(x == tuple(sub) for x in zip(sequence, sequence[1:]))
# 5

В более общем плане это

windows = zip(*([sequence[i:] for i, _ in enumerate(sequence)][:len(sub)]))
sum(x == tuple(sub) for x in windows)
# 5

или распространяются на генераторы:

import itertools as it


iter_ = (sequence[i:] for i, _ in enumerate(sequence))
windows = zip(*(it.islice(iter_, None, len(sub))))
sum(x == tuple(sub) for x in windows)

альтернатива

Вы можете использовать more_itertools.locate:

import more_itertools as mit


len(list(mit.locate(sequence, pred=lambda *args: args == tuple(sub), window_size=len(sub))))
# 5

Ответ 20

Простой способ подсчета вхождения подстроки состоит в использовании count():

>>> s = 'bobob'
>>> s.count('bob')
1

Вы можете использовать replace() чтобы найти перекрывающиеся строки, если вы знаете, какая часть будет перекрываться:

>>> s = 'bobob'
>>> s.replace('b', 'bb').count('bob')
2

Обратите внимание, что помимо статичности, есть и другие ограничения:

>>> s = 'aaa'
>>> count('aa') # there must be two occurrences
1 
>>> s.replace('a', 'aa').count('aa')
3

Ответ 21

def occurance_of_pattern(text, pattern):
    text_len , pattern_len = len(text), len(pattern)
    return sum(1 for idx in range(text_len - pattern_len + 1) if text[idx: idx+pattern_len] == pattern) 

Ответ 22

Если вы хотите подсчитать количество перестановок длины 5 (отрегулируйте, если хотите для разных длин):

def MerCount(s):
  for i in xrange(len(s)-4):
    d[s[i:i+5]] += 1
return d

Ответ 23

sum([ 1 for _ in range(len(string)-len(str_to_search_for)+1) if string[_:_+len(str_to_search_for)] == str_to_search_for])

В понимании списка мы перемещаем большую строку по одной позиции за раз с скользящим окном длины меньшей строки. Мы можем вычислить скользящее число, вычитая длину меньшей строки из большей строки. Для каждого слайда мы сравниваем ту часть большей строки с нашей меньшей строкой и генерируем 1 в списке, если совпадение найдено. Сумма всех этих 1 в списке даст нам общее количество найденных совпадений.