किसी स्ट्रिंग में दिए गए सबस्ट्रिंग की घटनाओं की संख्या


202

पायथन में एक स्ट्रिंग के भीतर किसी दिए गए सबस्ट्रिंग की संख्या कितनी बार गिना जा सकता है?

उदाहरण के लिए:

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

"प्रतिस्थापन की संख्या" से आपका क्या तात्पर्य है? स्थानापन्न की स्थिति? प्रतिस्थापन कितनी बार होता है? कुछ और?
ग्रीनमैट

2
क्या यह एक होमवर्क असाइनमेंट है? यदि हां, तो कृपया अपने प्रश्न में "होमवर्क" टैग जोड़ें। साथ ही, आपका प्रश्न बहुत स्पष्ट नहीं है। मैं जवाब दूंगा कि आप क्या पूछ रहे हैं, लेकिन मुझे संदेह है कि आप वास्तव में कुछ और जानना चाहते हैं।
जिम डेलाउंट

पिछली टिप्पणी के बाद, आप देखना चाह सकते हैं: अजगर: कैसे एक स्ट्रिंग में एक स्ट्रिंग खोजने के लिए या स्ट्रिंग (अजगर) के भीतर एक विकल्प के मूल अनुक्रमण आवर्ती । जैसा कि उन लोगों में से एक की एक संभावित नकल लगता है, मैं बंद करने के लिए मतदान कर रहा हूं।
ग्रीनमैट

@JimDeLaHunt रिकॉर्ड्स के लिए, cscircles.cemc.uwaterloo.ca/8-remix में इस बारे में एक अभ्यास है - देखें कोडिंग एक्सरसाइज: काउंटिंग काउंटिंग देखें
निकोस एलेक्जेंड्रिस

जवाबों:


335

string.count(substring), जैसे की:

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

अपडेट करें:

जैसा कि टिप्पणियों में बताया गया है, यह गैर अतिव्यापी घटनाओं के लिए ऐसा करने का तरीका है । यदि आपको अतिव्यापी घटनाओं की गणना करने की आवश्यकता है, तो आप बेहतर तरीके से उत्तरों की जांच करेंगे: " पायथन रेगेक्स सभी ओवरलैपिंग मैच ढूंढता है? ", या बस नीचे दिए गए मेरे अन्य उत्तर की जांच करें।


14
इस बारे में क्या है: "GCAAAAAG".count("AAA")जो 1 देता है, जबकि सही उत्तर 3 है?
कार्टूनिस्ट

12
countस्पष्ट रूप से गैर-अतिव्यापी मैचों के लिए - जो कि सबसे अधिक बार वही होता है जो कोई करना चाहता है। stackoverflow.com/questions/5616822/… ओवरलैपिंग मैचों से संबंधित है - लेकिन एक साधारण, यदि महंगा, अभिव्यक्ति है:sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
jsbueno

क्या एक साथ कई शब्दों को गिनना / खोजना संभव है? जैसे string.count (substring1, substring2)
सुशांत कुलकर्णी

@SushantKulkarni नहीं, हालांकि ऐसा करने का एक तार्किक तरीका है string.count(substring1) + string.count(substring2):। लेकिन ध्यान रखें कि यह एक कुशल विधि नहीं है यदि बहुत सारे सबस्ट्रिंग हैं क्योंकि प्रत्येक प्रतिस्थापन की गणना के लिए मुख्य स्ट्रिंग पर एक पुनरावृत्ति की आवश्यकता होती है।
फहील

@SushantKulkarni ''.join([substring1, substring2]).count(pattern)ऊपर दिए गए समाधान की तुलना में अधिक कुशल है। मैंने समयसीमा का उपयोग करके जाँच की।
एनरिक कैलाबिग


19

आप वास्तव में क्या मतलब के आधार पर, मैं निम्नलिखित समाधान का प्रस्ताव:

  1. आपका मतलब अंतरिक्ष से अलग उप-स्ट्रिंग्स की एक सूची है और जानना चाहते हैं कि सभी उप-स्ट्रिंग्स के बीच उप-स्ट्रिंग स्थिति संख्या क्या है:

    s = 'sub1 sub2 sub3'
    s.split().index('sub2')
    >>> 1
  2. आप स्ट्रिंग में उप-स्ट्रिंग की चार-स्थिति का मतलब है:

    s.find('sub2')
    >>> 5
  3. आपका मतलब है (गैर-अतिव्यापी) एक सू-बस्ट्रिंग की उपस्थिति के मायने :

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

'सब' या 'सु' को खोजने का प्रयास करें
obohovyk

मुझे लगता है कि आप मतलब है s.find("su")और आश्चर्य है कि तुम क्यों हो 0? वैसे यह सब-स्ट्रिंग का पहला इंडेक्स "su"है s। प्रयास करें "ub"और आप देंगे 1, जैसे की कोशिश "z"और आप मिल जाएगा -1कोई सबस्ट्रिंग में के रूप में पाया।
डॉन प्रश्न

मेरा मतलब है कि आप हमेशा केवल पहला इंडेक्स पाते हैं, लेकिन सभी इंडेक्स नहीं, @ arun-kumar-khattri ने सही उत्तर दिया
obohovyk

मुझे राहत है कि @ अरुण-कुमार-खत्री ने "सही" उत्तर दिया, जिसकी आप तलाश कर रहे थे। शायद आपको jsbueno की टिप्पणियों पर एक अतिरिक्त नज़र डालनी चाहिए, कभी-कभी वे उन सवालों के जवाब देते हैं जो आपने अभी तक नहीं पूछे हैं।
डॉन प्रश्न

तीसरे दृष्टिकोण के लिए पसंद है। BTW, मुझे लगता है कि आपको यह उल्लेख करना चाहिए कि यह गैर-अतिव्यापी मामलों के लिए काम करता है।
ज़ीनब अब्बासिमज़र

12

किसी दिए गए स्ट्रिंग में ओवरलैपिंग उप-स्ट्रिंग को खोजने का सबसे अच्छा तरीका यह है कि पायथन नियमित अभिव्यक्ति का उपयोग करें यह नियमित अभिव्यक्ति पुस्तकालय का उपयोग करके सभी ओवरलैपिंग मिलान का पता लगाएगा। यहां बताया गया है कि इसे कैसे छोड़ा जाए, यह सबस्ट्रिंग है और दाईं ओर आप स्ट्रिंग को मिलान करने के लिए प्रदान करेंगे

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

2
हो सकता है कि आप उप स्ट्रिंग को गतिशील रूप से सम्मिलित करने के लिए len (re.findall (f '(? = {sub_string})', 'caaaab') जोड़ सकते हैं :)
Amesh Giri

10

पायथन 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  

मैंने खुद इस एल्गोरिथ्म की जाँच की और इसने काम किया।


1
छोटा टिप: यह कहने के बजाय कि "यह काम करता है क्योंकि मैंने इसे चेक किया था", आप कुछ नमूना डेटा के साथ repl.it जैसी ऑनलाइन सेवा पर एक उदाहरण शामिल कर सकते हैं ।
वैलेंटाइन

1
आपकी टिप्पणी वैलेंटाइन के लिए धन्यवाद! यह मेरा पहला उत्तर है। मैं अपने अगले उत्तरों से खुद को सुधार लूंगा।
भरत कुमार आर।

10

आप दो तरीकों का उपयोग करके आवृत्ति की गणना कर सकते हैं:

  1. का उपयोग count()में str:

    a.count(b)

  2. या, आप उपयोग कर सकते हैं:

    len(a.split(b))-1

जहां aस्ट्रिंग है और bवह सबस्ट्रिंग है जिसकी आवृत्ति की गणना की जानी है।


7

वर्तमान में शामिल सर्वोत्तम उत्तर विधि 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

6

परिदृश्य 1: एक वाक्य में एक शब्द की घटना। उदाहरण के लिए: str1 = "This is an example and is easy"। शब्द की घटना "है"। की सुविधा देता हैstr2 = "is"

count = str1.count(str2)

परिदृश्य 2: एक वाक्य में पैटर्न की घटना।

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

धन्यवाद!


क्या वास्तव में हमें इस जाँच की आवश्यकता है अगर (स्ट्रिंग [j] == सब_स्ट्रिंग [0]):? क्या यह स्वचालित रूप से बाद की स्थिति में शामिल नहीं है?
आनंदविश्वनाथन

AnandViswanathan89, यदि आवश्यक हो तो दोनों स्थितियों में, यदि (स्ट्रिंग [j] == sub_string [0]) मुख्य स्ट्रिंग के भीतर प्रारंभिक वर्ण मिलान के लिए जाँच करता है, जो मुख्य स्ट्रिंग के सभी वर्णों के लिए किया जाना है और यदि (स्ट्रिंग) j: j + len2] == sub_string) सबस्ट्रिंग घटना को अंजाम देता है। यदि यह पहली घटना के लिए है तो दूसरी यदि स्थिति पर्याप्त है।
अमीथ वीवी

4

सवाल बहुत स्पष्ट नहीं है, लेकिन मैं पूछूंगा कि आप सतह पर क्या हैं, पूछ रहे हैं।

एक स्ट्रिंग S, जो L वर्ण लंबा है, और जहाँ S [1] स्ट्रिंग का पहला वर्ण है और S [L] अंतिम वर्ण है, में निम्नलिखित उपसर्ग हैं:

  • अशक्त स्ट्रिंग ''। इनमें से एक है।
  • प्रत्येक मान A से 1 तक, A से L तक प्रत्येक मान B के लिए, स्ट्रिंग S [A] .. S [B] (समावेशी)। कुल 0.5 * L * (L + 1) इन स्ट्रिंग्स में L + L-1 + L-2 + ... 1 हैं।
  • ध्यान दें कि दूसरे आइटम में S [1] .. S [L], यानी संपूर्ण मूल स्ट्रिंग S शामिल हैं।

तो, लंबाई L. रेंडर की एक स्ट्रिंग के भीतर 0.5 * L * (L + 1) + 1 सबस्ट्रिंग हैं जो कि पायथन में अभिव्यक्ति है, और आपके पास स्ट्रिंग के भीतर मौजूद सबस्ट्रिंग की संख्या है।


4

एक तरीका है उपयोग करना re.subn। उदाहरण के लिए, आपके द्वारा किए जाने 'hello'वाले मामलों के किसी भी मिश्रण में होने वाली घटनाओं की संख्या की गणना करने के लिए:

import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of "hello"')

मेरे लिए शब्द, धन्यवाद। @ संतोष, जवाब क्यों नहीं स्वीकार करते?
मावग का कहना है कि

2

मैं अपने स्वीकृत उत्तर को "इसे करने का सरल और स्पष्ट तरीका" कहूँगा - हालाँकि, यह अतिव्यापी घटनाओं को कवर नहीं करता है। उन लोगों का पता लगाना जो भोलेपन से किए जा सकते हैं, जैसे कि स्लाइस की कई जाँच के साथ - योग में ("जीसीएएएएएजीएच" [i]]। प्रारंभ (मैं (जीसीएएएजीएएचएच)) के लिए रेंज में ("एएए"))।

(जो पैदावार 3) - यह नियमित अभिव्यक्तियों के ट्रिक उपयोग द्वारा किया जा सकता है, जैसा कि पायथन रेगेक्स में देखा जा सकता है कि सभी ओवरलैपिंग मैच मिले? - और यह ठीक कोड गोल्फिंग के लिए भी बना सकता है - यह एक स्ट्रिंग में पैटर्न के अतिव्यापीता के लिए मेरी "हाथ से बनाई गई" गिनती है जो बेहद भोला नहीं होने की कोशिश करता है (कम से कम यह प्रत्येक इंटरैक्शन में नए स्ट्रिंग ऑब्जेक्ट नहीं बनाता है):

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

अतिव्यापी घटनाएँ:

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

2

अतिव्यापी गिनती के लिए हम उपयोग कर सकते हैं:

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

गैर-अतिव्यापी मामले के लिए हम गिनती () फ़ंक्शन का उपयोग कर सकते हैं:

string.count(sub_string)

2

कैसे एक सूची समझ के साथ एक लाइनर के बारे में? तकनीकी रूप से इसके 93 अक्षर लंबे, मुझे PEP-8 शुद्धतावाद से अलग करते हैं। Regex.findall उत्तर सबसे पठनीय है यदि इसका उच्च स्तरीय कोड है। यदि आप कुछ निम्न स्तर का निर्माण कर रहे हैं और निर्भरता नहीं चाहते हैं, तो यह बहुत ही दुबला और क्षुद्र है। मैं ओवरलैपिंग जवाब दे रहा हूं। ओवरलैप न होने पर स्पष्ट रूप से केवल उच्चतम स्कोर उत्तर की तरह गिनती का उपयोग करें।

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

यदि आप सभी उप-स्ट्रिंग (अतिव्यापी सहित) की गणना करना चाहते हैं तो इस विधि का उपयोग करें।

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

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

0

मुझे यकीन नहीं है कि अगर यह कुछ पहले से ही देखा गया है, लेकिन मैंने इसे एक शब्द के लिए एक समाधान के रूप में सोचा जो 'डिस्पोजेबल' है:

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

print count

जहां शब्द वह शब्द है जिसे आप खोज रहे हैं और शब्द वह शब्द है जिसे आप खोज रहे हैं


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
हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन समस्या को हल करने के तरीके के बारे में अतिरिक्त संदर्भ प्रदान करता है और यह समस्या को हल करता है ताकि उत्तर के दीर्घकालिक मूल्य में सुधार हो सके।
डोनाल्ड डक

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

यह स्ट्रिंग में पाए जाने वाले उप स्ट्रिंग की संख्या को प्रदर्शित करता है और सूचकांक प्रदर्शित करता है।


import re d = [m.start () in m for re.finditer (st3, st2)] # बार स्ट्रिंग और डिस्प्ले इंडेक्स प्रिंट में पाए जाने वाले सब स्ट्रिंग की संख्या को निर्धारित करना (d)
भास्कर रेड्डी 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

एक नीचा दिखाना क्योंकि 2+ अन्य लोगों ने पहले ही यह समाधान प्रदान किया है। मैंने भी उनमें से एक को उकसाया। लेकिन मेरा शायद newbies समझने के लिए सबसे आसान है।

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

अंतरिक्ष परिसीमन के साथ एक सरल स्ट्रिंग के लिए, डिक्ट का उपयोग करना काफी तेज होगा, कृपया नीचे दिए गए कोड को देखें

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

नीचे तर्क सभी स्ट्रिंग और विशेष वर्णों के लिए काम करेगा

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

यहाँ पायथन 3 और मामले असंवेदनशील में समाधान है:

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
जबकि सभी उत्तरों की सराहना की जाती है, कोड केवल उत्तर बहुत अच्छे विषय की व्याख्या नहीं करते हैं। कृपया कुछ संदर्भ जोड़ें।
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

यह स्ट्रिंग में सभी आवृत्तियों (ओवरलैपिंग) की एक सूची बनाता है और उन्हें गिनता है

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

उदाहरण:

str1 ='abcabcd'
str2 = 'bc'

यह सूची बनाएगा लेकिन केवल BOLD को बचाएगा मानों :

[एबी, बीसी , सीए, एबी, बीसी , सीडी]

वह वापस आ जाएगी:

len([bc, bc])

1
कृपया कम से कम कुछ स्पष्टीकरण जोड़ने पर विचार करें क्योंकि यह प्रश्न का उत्तर क्यों देता है
τ.τοιβε.βε

0

यहां एक समाधान है जो गैर-अतिव्यापी और अतिव्यापी दोनों घटनाओं के लिए काम करता है। स्पष्ट करने के लिए: एक अतिव्यापी विकल्प वह है जिसका अंतिम वर्ण उसके पहले वर्ण के समान है।

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
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.