Hitung jumlah kemunculan substring yang diberikan dalam string

201

Bagaimana saya bisa menghitung berapa kali substring yang diberikan hadir dalam string dengan Python?

Sebagai contoh:

>>> 'foo bar foo'.numberOfOccurrences('foo')
2
santosh
sumber
Apa yang Anda maksud dengan "jumlah substring"? Posisi substring? Berapa kali substring terjadi? Sesuatu yang lain
GreenMatt
2
Apakah ini tugas pekerjaan rumah? Jika demikian, tambahkan tag "pekerjaan rumah" ke pertanyaan Anda. Juga, pertanyaan Anda tidak terlalu jelas. Saya akan menjawab apa yang tampaknya Anda tanyakan, tetapi saya curiga Anda benar-benar ingin mencari tahu hal lain.
Jim DeLaHunt
Mengikuti komentar sebelumnya, Anda mungkin ingin melihat: python: Cara menemukan substring di string lain atau pengulangan pengindeksan dasar dari substring dalam string (python) . Karena ini sepertinya duplikat dari salah satunya, saya memilih untuk menutup.
GreenMatt
@JimDeLaHunt Untuk catatan, ada latihan tentang ini di cscircles.cemc.uwaterloo.ca/8-remix - lihat Latihan Pengkodean: Menghitung Substring .
Nikos Alexandris

Jawaban:

334

string.count(substring), seperti di:

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

Memperbarui:

Seperti yang ditunjukkan dalam komentar, ini adalah cara untuk melakukannya untuk kejadian yang tidak tumpang tindih . Jika Anda perlu menghitung kejadian yang tumpang tindih, Anda sebaiknya memeriksa jawabannya di: " Python regex menemukan semua kecocokan yang tumpang tindih? ", Atau cukup periksa jawaban saya yang lain di bawah ini.

jsbueno
sumber
14
Bagaimana dengan ini: "GCAAAAAG".count("AAA")yang memberi 1, sedangkan jawaban yang benar adalah 3?
kartunis
12
countjelas untuk pertandingan yang tidak tumpang tindih - yang paling sering ingin dilakukan seseorang. stackoverflow.com/questions/5616822/… berurusan dengan pertandingan yang tumpang tindih - tapi ekspresi sederhana, jika mahal, adalah:sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
jsbueno
Apakah mungkin menghitung / mencari beberapa kata sekaligus? seperti string.count (substring1, substring2)
Sushant Kulkarni
@SushantKulkarni No. Meskipun ada satu cara yang logis untuk melakukan hal tersebut: string.count(substring1) + string.count(substring2). Tetapi perlu diingat bahwa ini bukan metode yang efisien jika ada banyak substring karena menghitung setiap substring memerlukan iterasi atas string utama.
Faheel
@SushantKulkarni melakukan ''.join([substring1, substring2]).count(pattern)lebih efisien daripada solusi yang disarankan di atas. Saya diperiksa menggunakan timeit.
Enric Calabuig
23
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
Arun Kumar Khattri
sumber
4
Penjelasan tambahan akan meningkatkan jawaban Anda.
ryanyuyu
19

Tergantung apa yang Anda maksud, saya mengusulkan solusi berikut:

  1. Maksud Anda daftar sub-string yang dipisahkan ruang dan ingin tahu apa nomor posisi sub-string di antara semua sub-string:

    s = 'sub1 sub2 sub3'
    s.split().index('sub2')
    >>> 1
  2. Maksud Anda posisi char dari sub-string dalam string:

    s.find('sub2')
    >>> 5
  3. Anda berarti (non-overlapping) jumlah penampilan dari su-bstring:

    s.count('sub2')
    >>> 1
    s.count('sub')
    >>> 3
Don Question
sumber
Cobalah untuk menemukan 'sub' atau 'su'
obohovyk
Saya kira Anda bermaksud s.find("su")dan bertanya-tanya mengapa Anda mendapatkannya 0? Nah ini adalah indeks pertama dari sub-string "su"di s. Coba "ub"dan Anda akan mendapatkan 1, coba misalnya "z"dan Anda akan mendapatkan -1tidak ditemukan di substring.
Don Question
Maksud saya Anda selalu menemukan hanya indeks pertama, tetapi tidak semua indeks, @ arun-kumar-khattri memberikan jawaban yang benar
obohovyk
Saya lega bahwa @ arun-kumar-khattri memberikan jawaban "benar" yang Anda cari. Mungkin Anda harus melihat komentar jsbueno, terkadang mereka menjawab pertanyaan yang belum Anda tanyakan.
Don Question
Seperti untuk pendekatan ketiga. BTW, saya pikir Anda harus menyebutkan bahwa itu berfungsi untuk kasus yang tidak tumpang tindih.
Zeinab Abbasimazar
12

Cara terbaik untuk menemukan sub-string yang tumpang tindih dalam string yang diberikan adalah dengan menggunakan ekspresi reguler python, itu akan menemukan semua pencocokan yang tumpang tindih menggunakan perpustakaan ekspresi reguler. Berikut adalah cara melakukannya adalah substring dan di sebelah kanan Anda akan memberikan string yang cocok

print len(re.findall('(?=aa)','caaaab'))
3
Deepak Yadav
sumber
2
mungkin Anda bisa menambahkan len (re.findall (f '(? = {sub_string})', 'caaaab')) untuk memasukkan sub string secara dinamis :)
Amresh Giri
10

Untuk menemukan kejadian substring yang tumpang tindih dalam string dengan Python 3, algoritma ini akan melakukan:

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  

Saya sendiri memeriksa algoritme ini dan berhasil.

Bharath Kumar R
sumber
1
Kiat kecil: Alih-alih mengatakan "Ini berhasil karena saya memeriksanya", Anda dapat menyertakan contoh pada layanan online seperti repl.it dengan beberapa data sampel.
Valentin
1
terima kasih atas komentar Anda Valentin! Ini jawaban pertamaku di sini. Saya akan meningkatkan diri dari jawaban saya berikutnya.
Bharath Kumar R
10

Anda dapat menghitung frekuensi menggunakan dua cara:

  1. Menggunakan count()in str:

    a.count(b)

  2. Atau, Anda dapat menggunakan:

    len(a.split(b))-1

Di mana astring dan bmerupakan substring yang frekuensinya harus dihitung.

Anuj Gupta
sumber
7

Jawaban terbaik yang melibatkan metode saat countini tidak benar-benar diperhitungkan untuk kejadian yang tumpang tindih dan tidak peduli tentang sub-string kosong juga. Sebagai contoh:

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

Jawaban pertama seharusnya 2tidak 1, jika kita mempertimbangkan substring yang tumpang tindih. Adapun jawaban kedua lebih baik jika sub-string kosong mengembalikan 0 sebagai asnwer.

Kode berikut menangani hal-hal ini.

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

Sekarang ketika kita menjalankannya:

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

Skenario 1: Kejadian kata dalam sebuah kalimat. misalnya: str1 = "This is an example and is easy". Kemunculan kata "is". maristr2 = "is"

count = str1.count(str2)

Skenario 2: Kejadian pola dalam sebuah kalimat.

string = "ABCDCDC"
substring = "CDC"

def count_substring(string,sub_string):
    len1 = len(string)
    len2 = len(sub_string)
    j =0
    counter = 0
    while(j < len1):
        if(string[j] == sub_string[0]):
            if(string[j:j+len2] == sub_string):
                counter += 1
        j += 1

    return counter

Terima kasih!

Amith VV
sumber
apakah kita benar-benar memerlukan pemeriksaan ini jika (string [j] == sub_string [0]):? bukankah itu secara otomatis tercakup dalam kondisi jika berikutnya?
AnandViswanathan89
AnandViswanathan89, Kedua jika kondisi diperlukan, jika (string [j] == sub_string [0]) memeriksa kecocokan karakter awal dalam string utama, yang harus dilakukan untuk seluruh karakter string utama dan jika (string [ j: j + len2] == sub_string) melakukan kemunculan substring. Jika itu untuk kejadian pertama maka yang kedua jika kondisi sudah mencukupi.
Amith VV
4

Pertanyaannya tidak terlalu jelas, tetapi saya akan menjawab apa Anda, di permukaan, bertanya.

Sebuah string S, yang panjang karakter L, dan di mana S [1] adalah karakter pertama dari string dan S [L] adalah karakter terakhir, memiliki substring berikut:

  • String nol ''. Ada satu di antaranya.
  • Untuk setiap nilai A dari 1 hingga L, untuk setiap nilai B dari A ke L, string S [A] .. S [B] (inklusif). Ada L + L-1 + L-2 + ... 1 dari string ini, dengan total 0,5 * L * (L + 1).
  • Perhatikan bahwa item kedua termasuk S [1] .. S [L], yaitu seluruh string asli S.

Jadi, ada 0,5 * L * (L + 1) + 1 substring dalam string panjang L. Render ekspresi itu dalam Python, dan Anda memiliki jumlah substring hadir dalam string.

Jim DeLaHunt
sumber
4

Salah satu caranya adalah menggunakan re.subn. Misalnya, untuk menghitung jumlah kemunculan 'hello'dalam berbagai kasus yang dapat Anda lakukan:

import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')
Eugene Yarmash
sumber
Kata untuk saya, terima kasih. @ antosh, mengapa tidak menerima jawaban?
Mawg mengatakan mengembalikan Monica
2

Saya akan menjaga jawaban yang saya terima sebagai "cara sederhana dan jelas untuk melakukannya" - namun, itu tidak mencakup kejadian yang tumpang tindih. Mengetahui hal itu dapat dilakukan secara naif, dengan memeriksa beberapa irisan - seperti dalam: jumlah ("GCAAAAAGH" [i:]. Startswith ("AAA") untuk i dalam jangkauan (len ("GCAAAAAGH"))))

(Yang menghasilkan 3) - itu dapat dilakukan dengan trik menggunakan ekspresi reguler, seperti yang dapat dilihat di Python regex menemukan semua kecocokan yang tumpang tindih? - dan itu juga dapat membuat golf kode yang bagus - Ini adalah hitungan "buatan tangan" saya karena tumpang tindih pola-pola dalam string yang mencoba tidak terlalu naif (setidaknya tidak membuat objek string baru di setiap interaksi):

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))
jsbueno
sumber
2

Kejadian yang tumpang tindih:

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')

Hasil:

my maaather lies over the oceaaan
6
4
2
fyngyrz
sumber
2

Untuk jumlah yang tumpang tindih kita dapat menggunakan use:

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

Untuk kasus yang tidak tumpang tindih kita dapat menggunakan fungsi count ():

string.count(sub_string)
Dhiraj Dwivedi
sumber
2

Bagaimana dengan one-liner dengan pemahaman daftar? Secara teknis 93 karakternya panjang, lepaskan saya purisme PEP-8. Jawaban regex.findall adalah yang paling mudah dibaca jika merupakan kode tingkat tinggi. Jika Anda sedang membangun sesuatu tingkat rendah dan tidak ingin ketergantungan, yang ini sangat ramping dan kejam. Saya memberikan jawaban yang tumpang tindih. Tentunya gunakan saja hitungan seperti jawaban skor tertinggi jika tidak ada tumpang tindih.

def count_substring(string, sub_string):
    return len([i for i in range(len(string)) if string[i:i+len(sub_string)] == sub_string])
Ryan Dines
sumber
2

Jika Anda ingin menghitung semua sub-string (termasuk tumpang tindih) maka gunakan metode ini.

import re
def count_substring(string, sub_string):
    regex = '(?='+sub_string+')'
    # print(regex)
    return len(re.findall(regex,string))
Rahul Verma
sumber
1

Jika Anda ingin mengetahui jumlah substring di dalam string apa pun; silakan gunakan kode di bawah ini. Kode ini mudah dimengerti karena itu saya melewatkan komentar. :)

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
Hemant
sumber
0

Saya tidak yakin apakah ini sesuatu yang sudah dilihat, tetapi saya menganggap ini sebagai solusi untuk kata yang 'sekali pakai':

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

print count

Di mana kata adalah kata yang Anda cari dan istilah adalah istilah yang Anda cari

Alan Vinton
sumber
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)
kamran shaik
sumber
2
Mungkin Anda bisa menguraikan bagaimana solusi ini berbeda dari yang lain, apakah ada kasus khusus yang dapat diselesaikan?
mpaskov
2
Sementara kode ini dapat menjawab pertanyaan, memberikan konteks tambahan tentang bagaimana dan / atau mengapa memecahkan masalah akan meningkatkan nilai jangka panjang jawaban.
Donald Duck
0
import re
d = [m.start() for m in re.finditer(seaching, string)] 
print (d)

Ini menemukan berapa kali sub string ditemukan dalam string dan menampilkan indeks.

Bhaskar Reddi K
sumber
import re d = [m.start () untuk m di re.finditer (st3, st2)] #mencari berapa kali sub string ditemukan dalam string dan tampilkan indeks cetak (d)
Bhaskar Reddi K
0
my_string = """Strings are amongst the most popular data types in Python. 
               We can create the strings by enclosing characters in quotes.
               Python treats single quotes the same as double quotes."""

Count = my_string.lower().strip("\n").split(" ").count("string")
Count = my_string.lower().strip("\n").split(" ").count("strings")
print("The number of occurance of word String is : " , Count)
print("The number of occurance of word Strings is : " , Count)
Vinay Kumar Kuresi
sumber
0

Mempertaruhkan downvote karena 2+ orang lain telah menyediakan solusi ini. Saya bahkan membatalkan salah satu dari mereka. Tapi milikku mungkin yang paling mudah dipahami oleh pemula.

def count_substring(string, sub_string):
    slen  = len(string)
    sslen = len(sub_string)
    range_s = slen - sslen + 1
    count = 0
    for i in range(range_s):
        if (string[i:i+sslen] == sub_string):
            count += 1
    return count
BabarBaig
sumber
0

Untuk string sederhana dengan batasan ruang, menggunakan Dict akan cukup cepat, silakan lihat kode seperti di bawah ini

def getStringCount(mnstr:str, sbstr:str='')->int:
    """ Assumes two inputs string giving the string and 
        substring to look for number of occurances 
        Returns the number of occurances of a given string
    """
    x = dict()
    x[sbstr] = 0
    sbstr = sbstr.strip()
    for st in mnstr.split(' '):
        if st not in [sbstr]:
            continue
        try:
            x[st]+=1
        except KeyError:
            x[st] = 1
    return x[sbstr]

s = 'foo bar foo test one two three foo bar'
getStringCount(s,'foo')
Amit Gowda
sumber
0

Anda dapat menggunakan startswithmetode ini:

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

Logika di bawah ini akan berfungsi untuk semua karakter string & khusus

def cnt_substr(inp_str, sub_str):
    inp_join_str = ''.join(inp_str.split())
    sub_join_str = ''.join(sub_str.split())

    return inp_join_str.count(sub_join_str)

print(cnt_substr("the sky is   $blue and not greenthe sky is   $blue and not green", "the sky"))
skay
sumber
0

Inilah solusi dalam Python 3 dan case-sensitive:

s = 'foo bar foo'.upper()
sb = 'foo'.upper()
results = 0
sub_len = len(sb)
for i in range(len(s)):
    if s[i:i+sub_len] == sb:
        results += 1
print(results)
attachPost
sumber
0
j = 0
    while i < len(string):
        sub_string_out = string[i:len(sub_string)+j]
        if sub_string == sub_string_out:
            count += 1
        i += 1
        j += 1
    return count
vengat
sumber
2
Sementara semua jawaban dihargai, kode hanya jawaban cenderung tidak menjelaskan subjek dengan sangat baik. Harap tambahkan beberapa konteks.
creyD
0
#counting occurence of a substring in another string (overlapping/non overlapping)
s = input('enter the main string: ')# e.g. 'bobazcbobobegbobobgbobobhaklpbobawanbobobobob'
p=input('enter the substring: ')# e.g. 'bob'

counter=0
c=0

for i in range(len(s)-len(p)+1):
    for j in range(len(p)):
        if s[i+j]==p[j]:
            if c<len(p):
                c=c+1
                if c==len(p):
                    counter+=1
                    c=0
                    break
                continue
        else:
            break
print('number of occurences of the substring in the main string is: ',counter)
pawan kumar
sumber
0
s = input('enter the main string: ')
p=input('enter the substring: ')
l=[]
for i in range(len(s)):
    l.append(s[i:i+len(p)])
print(l.count(p))
pawan kumar
sumber
0

Ini membuat daftar semua kemunculan (juga tumpang tindih) dalam string dan menghitungnya

def num_occ(str1, str2):
    l1, l2 = len(str1), len(str2)
    return len([str1[i:i + l2] for i in range(l1 - l2 + 1) if str1[i:i + l2] == str2])

Contoh:

str1 ='abcabcd'
str2 = 'bc'

akan membuat daftar ini tetapi hanya menyimpan nilai BOLD :

[ab, bc , ca, ab, bc , cd]

itu akan kembali:

len([bc, bc])
Elad L.
sumber
1
Silakan pertimbangkan untuk menambahkan setidaknya beberapa penjelasan seolah-olah mengapa ini menjawab pertanyaan
β.εηοιτ.βε
0

Inilah solusi yang berfungsi untuk kejadian yang tidak tumpang tindih dan tumpang tindih. Untuk memperjelas: substring yang tumpang tindih adalah yang karakter terakhirnya identik dengan karakter pertamanya.

def substr_count(st, sub):
    # If a non-overlapping substring then just
    # use the standard string `count` method
    # to count the substring occurences
    if sub[0] != sub[-1]:
        return st.count(sub)

    # Otherwise, create a copy of the source string,
    # and starting from the index of the first occurence
    # of the substring, adjust the source string to start
    # from subsequent occurences of the substring and keep
    # keep count of these occurences
    _st = st[::]
    start = _st.index(sub)
    cnt = 0

    while start is not None:
        cnt += 1
        try:
            _st = _st[start + len(sub) - 1:]
            start = _st.index(sub)
        except (ValueError, IndexError):
            return cnt

    return cnt
mrs-qv7
sumber