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

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.


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

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

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

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.


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.


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

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!


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.


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

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

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

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)

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

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

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

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


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
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.


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)

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

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

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

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

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)

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

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)

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

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

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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.