2012-01-17 2 views
110

Можно создать дубликат:
Basic indexing recurrences of a substring within a string (python)Подсчет количества вхождений заданной подстроки в строке

Как я могу подсчитать, сколько раз данная подстрока присутствует в виде строки в Python ?

Например:

>>> 'foo bar foo'.numberOfOccurrences('foo') 
2 
+0

Что вы имеете в виду под «номером подстроки»? Позиция подстроки? Сколько раз происходит подстрока? Что-то другое? – GreenMatt

+2

Это домашнее задание? Если да, добавьте тег «домашнее задание» на свой вопрос. Кроме того, ваш вопрос не очень ясен. Я отвечу на то, что вы спрашиваете, но я подозреваю, что вы действительно хотите узнать что-то еще. –

+0

Следуя предыдущему комментарию, вы можете увидеть: [python: как найти подстроку в другой строке] (http://stackoverflow.com/questions/7361253/python-how-to-find-a-substring-in- другая строка) или [Базовые индексы индексирования подстроки в строке (python)] (http://stackoverflow.com/questions/6987702/basic-indexing-recurrences-of-a-substring-within--string- питон). Поскольку это кажется вероятным дубликатом одного из них, я голосую, чтобы закрыть. – GreenMatt

ответ

218

string.count(substring), как в:

>>> "abcdabcva".count("ab") 
2 

обновление: как указано в комментариях, это способ сделать это для не перекрывающихся вхождения. Если вам нужно посчитать совпадающие осколки, лучше проверить ответы на: «Python regex find all overlapping matches?» или просто проверить мой другой ответ ниже.

+1

OMG нет метода подсчета в классе String ???? –

+0

@saideshkilaru: Что ты говоришь? Метод «count» в классе строк - это именно то, что было использовано здесь. – jsbueno

+7

Как насчет этого: '" GCAAAAAG ".count (" AAA ")', который дает 1, а правильный ответ - 3? – cartoonist

13

В зависимости, что вы на самом деле означает, я предлагаю следующие решения:

1) Вы имеете в виду список разделенных пробелами подстроки и хотите знать, что подстрока номер позиции среди всех подстроки:

s = 'sub1 sub2 sub3' 
s.split().index('sub2') 
>>> 1 

2) Вы имеете в виду обугленного-позицию подстроки в строке:

s.find('sub2') 
>>> 5 

3) Вы имеете в виду (не перекрывающиеся) считает появления Су-Подстрока:

s.count('sub2') 
>>> 1 
s.count('sub') 
>>> 3 
+0

Попробуйте найти 'sub' или 'su' – obohovyk

+0

Я думаю, вы имеете в виду 's.find (" su ")' и задаетесь вопросом, почему вы получаете '0'? Ну, это первый индекс подстроки '' su '' in 's'. Попробуйте '' ub "', и вы получите '1', попробуйте, например. '' z "', и вы получите '-1', как в не найденной подстроке. –

+0

Я имею в виду, что вы всегда находите только первый индекс, но не все индексы, @ arun-kumar-khattri дал правильный ответ – obohovyk

4

вопрос не очень понятно, но я отвечу, что вы, на поверхности, спрашивая.

Строка S, которая имеет длину L символов, и где S [1] является первым символом строки и S [L], является последним символом, имеет следующие подстроки:

  • Нулевая string ''. Есть один из них.
  • Для каждого значения A от 1 до L для каждого значения B от A до L строка S [A] .. S [B] (включительно). Есть L + L-1 + L-2 + ... 1 из этих строк, для всего 0,5 * L * (L + 1).
  • Следует отметить, что второй элемент включает в себя S [1] .. S [L], т.е. всей исходной строки С.

Итак, есть 0,5 * L * (L + 1) + 1 подстрок в строке длины L. Измените это выражение в Python, и у вас есть количество подстрок, присутствующих в строке.

10
s = 'arunununghhjj' 
sb = 'nun' 
results = 0 
sub_len = len(sb) 
for i in range(len(s)): 
    if s[i:i+sub_len] == sb: 
     results += 1 
print results 
+2

Дополнительное объяснение улучшит ваш ответ. – ryanyuyu

+0

Отлично! Спасибо!!! – obohovyk

2

Я сдержу принятый ответ как «простой и очевидный способ сделать это», - тем не менее, что не распространяется на перекрывающихся вхождений. Выяснить, что это можно сделать наивно, с несколькими проверками срезов - как в: sum ("GCAAAAAGH" [i:].(«AAA») для i в диапазоне (len («GCAAAAAGH»))

(что дает 3) - это можно сделать путем использования регулярных выражений, как показано на рисунке Python regex find all overlapping matches?, - и это может также сделать для тонкой кода игры в гольф - Это мой «ручной» рассчитывать на overlappingocurrences шаблонов в строке, которая пытается не быть крайне наивным (по крайней мере, это не создает новые строковые объекты при каждом взаимодействии):

def find_matches_overlapping(text, pattern): 
    lpat = len(pattern) - 1 
    matches = [] 
    text = array("u", text) 
    pattern = array("u", pattern) 
    indexes = {} 
    for i in range(len(text) - lpat): 
     if text[i] == pattern[0]: 
      indexes[i] = -1 
     for index, counter in list(indexes.items()): 
      counter += 1 
      if text[i] == pattern[counter]: 
       if counter == lpat: 
        matches.append(index) 
        del indexes[index] 
       else: 
        indexes[index] = counter 
      else: 
       del indexes[index] 
    return matches 

def count_matches(text, pattern): 
    return len(find_matches_overlapping(text, pattern)) 
0

Я не уверен, что это уже что-то посмотрело, но я подумал об этом как о решении для слова «одноразовое»:

for i in xrange(len(word)): 
if word[:len(term)] == term: 
    count += 1 
word = word[1:] 

print count 

Где слово это слово, которое вы ищете в и термин это термин, который вы ищете

2

внахлест вхождений:

def olpcount(string,pattern,case_sensitive=True): 
    if case_sensitive != True: 
     string = string.lower() 
     pattern = pattern.lower() 
    l = len(pattern) 
    ct = 0 
    for c in range(0,len(string)): 
     if string[c:c+l] == pattern: 
      ct += 1 
    return ct 

test = 'my maaather lies over the oceaaan' 
print test 
print olpcount(test,'a') 
print olpcount(test,'aa') 
print olpcount(test,'aaa') 

Результаты:

my maaather lies over the oceaaan 
6 
4 
2 
0
string="abc" 
mainstr="ncnabckjdjkabcxcxccccxcxcabc" 
count=0 
for i in range(0,len(mainstr)): 
    k=0 
    while(k<len(string)): 
     if(string[k]==mainstr[i+k]): 
      k+=1 
     else: 
      break 
    if(k==len(string)): 
     count+=1; 
print(count) 
+2

Возможно, вы можете уточнить, как это решение отличается от другого, есть ли специальный случай, который он может решить? – mpaskov

+2

Хотя этот код может ответить на вопрос, предоставление дополнительного контекста относительно того, как и/или почему оно решает проблему, улучшит долгосрочную ценность ответа. –

4

Текущий лучший ответ, включающий метод count, на самом деле не учитывает перекрывающиеся вхождения и не заботится о пустых подстроках. Например:

>>> a = 'caatatab' 
>>> b = 'ata' 
>>> print(a.count(b)) #overlapping 
1 
>>>print(a.count('')) #empty string 
9 

Первый ответ должен быть 2 не 1, если мы будем рассматривать перекрывающихся подстроки. Что касается второго ответа, то лучше, если пустая подстрока возвращает 0 в качестве asnwer.

Следующий код позаботится об этих вещах.

def num_of_patterns(astr,pattern): 
    astr, pattern = astr.strip(), pattern.strip() 
    if pattern == '': return 0 

    ind, count, start_flag = 0,0,0 
    while True: 
     try: 
      if start_flag == 0: 
       ind = astr.index(pattern) 
       start_flag = 1 
      else: 
       ind += 1 + astr[ind+1:].index(pattern) 
      count += 1 
     except: 
      break 
    return count 

Теперь, когда мы запускаем его:

>>>num_of_patterns('caatatab', 'ata') #overlapping 
2 
>>>num_of_patterns('caatatab', '') #empty string 
0 
>>>num_of_patterns('abcdabcva','ab') #normal 
2 
3

Чтобы найти перекрывающиеся вхождения подстроки в строке в Python 3, этот алгоритм будет делать:

def count_substring(string,sub_string): 
    l=len(sub_string) 
    count=0 
    for i in range(len(string)-len(sub_string)+1): 
     if(string[i:i+len(sub_string)] == sub_string):  
      count+=1 
    return count 

Я сам проверил это алгоритм, и это сработало.

+0

Маленький совет: вместо того, чтобы говорить «Это работает, потому что я проверил его», вы можете включить пример в онлайн-службу, например https://repl.it, с некоторыми примерами данных. – Valentin

+1

спасибо за ваш комментарий Валентин! Это мой первый ответ. Я улучшу себя от своих следующих ответов. –

1

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

string=raw_input() 
sub_string=raw_input() 
start=0 
answer=0 
length=len(string) 
index=string.find(sub_string,start,length) 
while index<>-1: 
    start=index+1 
    answer=answer+1 
    index=string.find(sub_string,start,length) 
print answer 
2

Вы можете рассчитывать частоту, используя два способа:

  1. Использование COUNT() в ул:

    a.count (б)

  2. Или, вы можете использовать:

    len (a.(b)) - 1

Где 'a' - это строка, а 'b' - подстрока, частота которой должна быть рассчитана.

0

Для перекрытия подсчетов мы можем использовать использование:

def count_substring(string, sub_string): 
    count=0 
    beg=0 
    while(string.find(sub_string,beg)!=-1) : 
     count=count+1 
     beg=string.find(sub_string,beg) 
     beg=beg+1 
    return count 

В неперекрывающихся случае мы можем использовать функцию Count():

string.count(sub_string) 
0
import re 
d = [m.start() for m in re.finditer(seaching, string)] 
print (d) 

Это находит число раз подстроки найденный в строке и отображающий индекс.

+0

import re d = [m.start() for m in re.finditer (st3, st2)] #finding количество подстрок, найденных в строке, и индекс отображения print (d) –

1

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

print len(re.findall('(?=aa)','caaaab')) 
3 
0

Один из способов заключается в использовании re.subn. Например, чтобы подсчитать количество вхождений 'hello' в любом сочетании случаях вы можете сделать:

import re 
_, count = re.subn(r'hello', '', astring, flags=re.I) 
print('Found', count, 'occurrences of "hello"') 
Смежные вопросы