计算字符串中子字符串出现的次数

Posted

技术标签:

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

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

例如:

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

【问题讨论】:

“子串的数量”是什么意思?子串的位置?子串出现多少次?还有什么? 这是家庭作业吗?如果是这样,请在您的问题中添加标签“作业”。另外,你的问题不是很清楚。我会回答你似乎在问的问题,但我怀疑你真的想找出其他东西。 在之前的评论之后,您可能希望看到:python: How to find a substring in another string 或 Basic indexing recurrences of a substring within a string (python)。由于这似乎与其中一个重复,我投票结束。 @JimDeLaHunt 作为记录,cscircles.cemc.uwaterloo.ca/8-remix 中有一个关于此的练习——请参阅编码练习:子字符串计数 Basic indexing recurrences of a substring within a string (python)的可能重复 【参考方案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 显然适用于非重叠匹配——这通常是人们想要做的。 ***.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】:

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

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

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

    你的意思是字符串中子字符串的字符位置:

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

    您的意思是子字符串出现的(不重叠的)计数

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

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

    str 中使用count()

    a.count(b)

    或者,您可以使用:

    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

【讨论】:

以上是关于计算字符串中子字符串出现的次数的主要内容,如果未能解决你的问题,请参考以下文章

C语言课程设计题目计算字符串中子串出现的次数

计算字符串中子字符串出现的次数

急求。。。C语言实现,计算字符串中子串出现的次数,比如输入GACTC,要求输出GA,AC,CT,TC出现的次数

计算字符串中子字符串的所有非重叠出现次数[重复]

计算 pyspark df 列中子字符串列表的出现次数

C语言试题159之计算字符串中子串出现的次数