【问题标题】:Count number of occurrences of a substring in a string计算字符串中子字符串出现的次数
【发布时间】:2012-02-12 13:38:43
【问题描述】:

如何计算给定子字符串在 Python 中的字符串中出现的次数?

例如:

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

【问题讨论】:

标签: python string


【解决方案1】:
def count_substring(string, sub_string):
    k=len(string)
    m=len(sub_string)
    i=0
    l=0
    count=0
    while l<k:
        if string[l:l+m]==sub_string:
            count=count+1
        l=l+1
    return count

if __name__ == '__main__':
    string = input().strip()
    sub_string = input().strip()

    count = count_substring(string, sub_string)
    print(count)

【讨论】:

  • 嗨。请解释您的解决方案。
【解决方案2】:

如果您正在寻找适用于所有情况的电源解决方案,此功能应该可以工作:

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

【讨论】:

    【解决方案3】:
    def count_substring(string, sub_string):
        counterList=[ 1 for i in range(len(string)-len(sub_string)+1) if string[i:i+len(sub_string)] == sub_string]
        count=sum(counterList)
        return count
    
    if __name__ == '__main__':
        string = input().strip()
        sub_string = input().strip()
    
        count = count_substring(string, sub_string)
        print(count)
    

    【讨论】:

      【解决方案4】:

      如果你想计算整个字符串,这可以工作。

      stri_count="If you're looking to count the whole string this can works"
      print(len(stri_count))
      

      【讨论】:

      • 嗨,Jean,欢迎来到 Stack Overflow!虽然这是有趣的信息,但遗憾的是它并没有回答最初提出的问题 - 请考虑添加有趣的信息,这些信息不是对未来作为 cmets 提出的问题的直接答案。除此之外,x.count('') 实际上返回字符串长度 + 1。len(x) 将是检索字符串长度的更典型方法。
      【解决方案5】:
      def count_substring(string, sub_string):
          inc = 0
          for i in range(0, len(string)):
              slice_object = slice(i,len(sub_string)+i)
              count = len(string[slice_object])
              if(count == len(sub_string)):
                  if(sub_string == string[slice_object]):
                      inc = inc + 1
          return inc
      
      if __name__ == '__main__':
          string = input().strip()
          sub_string = input().strip()
      
          count = count_substring(string, sub_string)
          print(count)
      

      【讨论】:

      • 附上这段代码的解释会很有帮助。
      【解决方案6】:

      这是一个适用于非重叠和重叠事件的解决方案。澄清一下:重叠子字符串的最后一个字符与其第一个字符相同。

      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
      

      【讨论】:

      • 重叠子字符串是最后一个字符与其第一个字符相同的子字符串 并且其长度为&gt; 1 - 否则为'a',对于例如,将是一个重叠的子字符串。为聪明的想法 +1。
      • 经过一番思考后,我得出结论,这个定义(关于第一个和最后一个字符)是错误的 - 考虑子字符串laplap
      【解决方案7】:

      场景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
      

      谢谢!

      【讨论】:

      • 我们真的需要这个检查 if(string[j] == sub_string[0]): 吗?后面的if条件不是自动覆盖了吗?
      • AnandViswanathan89,Both if 条件都需要, if(string[j] == sub_string[0]) 检查主字符串中的初始字符匹配,必须对整个字符执行主字符串和 if(string[j:j+len2] == sub_string) 执行子字符串的出现。如果是第一次出现,那么第二次如果条件就足够了。
      【解决方案8】:

      这将列出字符串中所有出现(也重叠)的列表并计算它们

      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 值:

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

      这将返回:

      len([bc, bc])
      

      【讨论】:

      • 请考虑添加至少一些解释,好像为什么这回答了这个问题
      【解决方案9】:

      string.count(substring),比如:

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

      更新:

      正如 cmets 中所指出的,这是针对 非重叠 事件的方法。如果您需要计算重叠出现的次数,您最好查看以下答案:“Python regex find all overlapping matches?”,或者只需查看下面我的其他答案。

      【讨论】:

      • 这个呢:"GCAAAAAG".count("AAA") 给出 1,而正确答案是 3?
      • count 显然适用于非重叠匹配——这通常是人们想要做的。 stackoverflow.com/questions/5616822/… 处理重叠匹配 - 但一个简单但昂贵的表达式是:sum("GCAAAAAGH"[i:].startswith("AAA") for i in range(len("GCAAAAAGH")))
      • 是否可以一次计算/搜索多个单词?像 string.count(substring1, substring2)
      • @SushantKulkarni 不。虽然有一种合乎逻辑的方式来做这样的事情:string.count(substring1) + string.count(substring2)。但是请记住,如果有很多子字符串,这不是一种有效的方法,因为计算每个子字符串需要对主字符串进行迭代。
      • @SushantKulkarni 做''.join([substring1, substring2]).count(pattern) 比上面建议的解决方案更有效。我使用 timeit 进行了检查。
      【解决方案10】:

      如果你想统计所有的子串(包括重叠的)那么就用这个方法。

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

      【讨论】:

        【解决方案11】:
        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))
        

        【讨论】:

          【解决方案12】:
          #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)
          

          【讨论】:

            【解决方案13】:
            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
            

            【讨论】:

            • 虽然所有答案都值得赞赏,但仅代码的答案往往不能很好地解释该主题。请添加一些上下文。
            【解决方案14】:

            这是 Python 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)
            

            【讨论】:

              【解决方案15】:

              根据您的实际意思,我提出以下解决方案:

              1. 您的意思是一个空格分隔的子字符串列表,并且想知道所有子字符串中的子字符串位置编号是多少:

                s = 'sub1 sub2 sub3'
                s.split().index('sub2')
                >>> 1
                
              2. 你的意思是字符串中子字符串的字符位置:

                s.find('sub2')
                >>> 5
                
              3. 您的意思是子字符串出现的(不重叠的)计数

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

              【讨论】:

              • 尝试查找“sub”或“su”
              • 我猜你的意思是s.find("su"),想知道为什么你会得到0?这是s 中子字符串"su" 的第一个索引。试试"ub",你会得到1,试试例如"z",你会得到-1,因为没有找到子字符串。
              • 我的意思是你总是只找到第一个索引,而不是所有索引,@arun-kumar-khattri 给出了正确答案
              • @arun-kumar-khattri 给出了您正在寻找的“正确”答案,这让我松了一口气。也许你应该多看看 jsbueno 的 cmets,有时他们会回答你还没问过的问题。
              • 喜欢第三种方法。顺便说一句,我认为您应该提到它适用于不重叠的情况。
              【解决方案16】:

              以下逻辑适用于所有字符串和特殊字符

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

              【讨论】:

                【解决方案17】:

                您可以使用startswith 方法:

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

                【讨论】:

                  【解决方案18】:

                  对于一个带空格分隔的简单字符串,使用Dict会很快,请看下面的代码

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

                  【讨论】:

                    【解决方案19】:

                    您可以使用两种方式计算频率:

                    1. str 中使用count()

                      a.count(b)

                    2. 或者,您可以使用:

                      len(a.split(b))-1

                    其中a 是字符串,b 是要计算其频率的子字符串。

                    【讨论】:

                      【解决方案20】:

                      冒着投反对票的风险,因为 2+ 其他人已经提供了此解决方案。我什至对其中一个投了赞成票。但我的可能是新手最容易理解的。

                      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
                      

                      【讨论】:

                        【解决方案21】:

                        带有列表理解的单行代码怎么样?从技术上讲,它有 93 个字符长,请放过我 PEP-8 纯粹主义。 regex.findall 答案是最易读的,如果它是一段高级代码。如果您正在构建低级别的东西并且不想要依赖关系,那么这个非常精简和平均。我给出了重叠的答案。显然,如果没有重叠,只需使用 count 作为最高分答案。

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

                        【讨论】:

                          【解决方案22】:
                          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)
                          

                          【讨论】:

                            【解决方案23】:

                            一种方法是使用re.subn。例如,要计算数量 'hello' 在你可以做的任何情况下出现:

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

                            【讨论】:

                            • 告诉我,谢谢。 @santosh,为什么不接受答案?
                            【解决方案24】:

                            在给定字符串中查找重叠子字符串的最佳方法是使用 python 正则表达式,它将使用正则表达式库查找所有重叠匹配。左边是子字符串,右边是要匹配的字符串

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

                            【讨论】:

                            • 也许你可以添加 len(re.findall(f'(?={sub_string})','caaaab')) 动态插入子字符串:)
                            【解决方案25】:
                            import re
                            d = [m.start() for m in re.finditer(seaching, string)] 
                            print (d)
                            

                            这会查找在字符串中找到子字符串的次数并显示索引。

                            【讨论】:

                            • import re d = [m.start() for m in re.finditer(st3, st2)] #查找子字符串在字符串中找到的次数并显示索引 print(d)
                            【解决方案26】:

                            对于重叠计数,我们可以使用:

                            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)
                            

                            【讨论】:

                              【解决方案27】:

                              如果您想找出任何字符串中的子字符串的计数;请使用下面的代码。 代码很容易理解,这就是我跳过 cmets 的原因。 :)

                              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
                              

                              【讨论】:

                                【解决方案28】:

                                要在 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  
                                

                                我自己检查了这个算法,它确实有效。

                                【讨论】:

                                • 小提示:您可以在repl.it 之类的在线服务中包含一些示例数据,而不是说“它有效,因为我检查了它”。
                                • 感谢您的评论瓦伦丁!这是我在这里的第一个答案。我会从下一个答案中改进自己。
                                【解决方案29】:

                                涉及方法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
                                

                                【讨论】:

                                  【解决方案30】:

                                  重叠出现:

                                  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
                                  

                                  【讨论】:

                                    猜你喜欢
                                    • 2020-02-21
                                    • 1970-01-01
                                    • 2014-04-24
                                    • 2022-01-09
                                    • 1970-01-01
                                    • 1970-01-01
                                    相关资源
                                    最近更新 更多