如何计算Python中字符串中给定子字符串的出现次数?
例如:
1
2>>> 'foo bar foo'.numberOfOccurrences('foo')
2
"子串数"是什么意思?子串的位置?子串出现多少次?别的什么?
这是家庭作业吗?如果是这样,请在您的问题中添加标签"homework"。另外,你的问题不是很清楚。我会回答你的问题,但我怀疑你真的想找到别的东西。
按照之前的注释,您可能希望看到:python:如何在另一个字符串中查找子字符串或者在字符串(python)中查找子字符串的基本索引重复。由于这似乎可能与其中一个重复,我投票结束。
@JimDeLaHunt有关记录,请参阅cscircles.cemc.uwaterloo.ca/8-remix中有关此内容的练习 - 请参阅编码练习:子字符串计数。
有趣的是在cscircles.cemc.uwaterloo.ca/8-remix中找到的练习是,要求的是子串出现的次数,无论其出现是否重叠。
字符串中子字符串的基本索引重复的可能重复(python)
string.count(substring),如:
1
2>>>"abcdabcva".count("ab")
2
更新:
正如评论中所指出的,这是非重叠事件的方法。如果你需要计算重叠的事件,你最好检查一下答案:"Python正则表达式找到所有重叠的匹配?",或者只是检查我的其他答案。
@saideshkilaru:你在说什么?字符串类中的"count"方法正是这里使用的方法。
怎么样:"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)。但请记住,如果存在大量子字符串,这不是一种有效的方法,因为计算每个子字符串需要对主字符串进行迭代。
执行''.join([substring1, substring2]).count(pattern)的@SushantKulkarni比上面建议的解决方案更有效。我用timeit检查过。
在诸如"ABCDCDC".count("CDC")之类的棘手案件中,它将失败。
1
2
3
4
5
6
7
8s = '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
其他解释可以改善您的答案。
完美匹配重叠匹配,谢谢!
根据您的真实含义,我提出以下解决方案:
你的意思是一个空格分隔的子字符串列表,并想知道所有子字符串中的子字符串位置编号是什么:
1
2
3s = 'sub1 sub2 sub3'
s.split().index('sub2')
>>> 1
你的意思是字符串中子字符串的char位置:
1
2s.find('sub2')
>>> 5
你的意思是su-bstring的外观(非重叠):
1
2
3
4s.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的评论,有时他们会回答你刚才没有提出的问题。
喜欢第三种方法。顺便说一句,我认为你应该提到它适用于非重叠的情况。
这应该是公认的答案
您可以使用两种方式计算频率:
使用str中的count():
<5233>
或者,您可以使用:
len(a.split(b))-1
其中a是字符串,b是要计算其频率的子字符串。
在给定字符串中查找重叠子字符串的最佳方法是使用python正则表达式,它将使用正则表达式库找到所有重叠匹配。以下是如何执行它左边是子字符串,在右边你将提供匹配的字符串
1
2print len(re.findall('(?=aa)','caaaab'))
3
要在Python 3中查找字符串中子字符串的重叠出现,此算法将执行以下操作:
1
2
3
4
5
6
7def 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这样的在线服务上加上一些示例数据,而不是说"它的工作原理,因为我检查了它"。
谢谢你的评论Valentin!这是我的第一个答案。我将从下一个答案中提高自己。
涉及方法count的当前最佳答案并不真正计算重叠事件,也不关心空子字符串。
例如:
1
2
3
4
5
6>>> a = 'caatatab'
>>> b = 'ata'
>>> print(a.count(b)) #overlapping
1
>>>print(a.count('')) #empty string
9
如果我们考虑重叠的子串,第一个答案应该是2而不是1。
至于第二个答案,如果空子字符串返回0作为asnwer则更好。
以下代码负责这些事情。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def 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
现在我们运行它:
1
2
3
4
5
6>>>num_of_patterns('caatatab', 'ata') #overlapping
2
>>>num_of_patterns('caatatab', '') #empty string
0
>>>num_of_patterns('abcdabcva','ab') #normal
2
问题不是很清楚,但我会从表面上回答你的问题。
字符串S,长度为L个字符,其中S [1]是字符串的第一个字符,S [L]是最后一个字符,具有以下子字符串:
空字符串''。其中之一就是其中之一。
对于从1到L的每个值A,对于从A到L的每个值B,字符串S [A] .. S [B]
(包括的)。这些字符串中有L + L-1 + L-2 + ... 1,用于a
总计0.5 * L *(L + 1)。
注意,第二项包括S [1] .. S [L],
即整个原始字符串S.
因此,在长度为L的字符串中有0.5 * L *(L + 1)+ 1个子串。在Python中渲染该表达式,并且您具有字符串中存在的子串数。
一种方法是使用re.subn。例如,要计算数量
在任何情况下你可以做的事件中出现'hello':
1
2
3import re
_, count = re.subn(r'hello', '', astring, flags=re.I)
print('Found', count, 'occurrences of"hello"')
对我说话,谢谢。 @santosh,为什么不接受答案?
我会将我接受的答案保持为"简单而明显的方式" - 然而,这并不包括重叠事件。
找出那些可以天真地完成,多次检查切片 - 如:
sum("GCAAAAAGH"[i:]。startswith("AAA")for i in range(len("GCAAAAAGH")))
(产生3) - 它可以通过使用正则表达式来完成,可以在Python正则表达式中找到所有重叠匹配? - 它还可以打造优质的高尔夫球 -
这是我的"手工制作"计数,用于在字符串中重复出现模式,这些模式试图不是非常幼稚(至少它不会在每次交互时创建新的字符串对象):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23def 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))
重叠发生:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16def 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')
结果:
1
2
3
4my maaather lies over the oceaaan
6
4
2
对于重叠计数,我们可以使用:
1
2
3
4
5
6
7
8def 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()函数:
1string.count(sub_string)
场景1:句子中出现的单词。
例如:str1 ="This is an example and is easy"。"是"这个词的出现。让str2 ="is"
1count = str1.count(str2)
场景2:句子中出现模式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15string ="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]):?是否在后续条件中自动涵盖?
AnandViswanathan89,两者都需要条件,if(string [j] == sub_string [0])检查主字符串中的初始字符匹配,必须对主字符串的整个字符执行if和if [string [ j:j + len2] == sub_string)执行子串出现。如果它是第一次出现那么第二次,如果条件就足够了。
如何使用列表理解的单行程?从技术上讲,它的长度为93个字符,饶了PEP-8纯粹主义。 regex.findall答案是最可读的,如果它是一个高级代码。如果你正在构建低级别的东西并且不想要依赖,那么这个非常精简和卑鄙。我给出了重叠的答案。如果没有重叠,显然只是使用计数像最高分答案。
1
2def count_substring(string, sub_string):
return len([i for i in range(len(string)) if string[i:i+len(sub_string)] == sub_string])
如果你想找出任何字符串中的子字符串数;请使用以下代码。
代码很容易理解,这就是我跳过评论的原因。 :)
1
2
3
4
5
6
7
8
9
10
11string=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
1
2
3
4
5
6s = 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))
评论代码会很好。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20#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
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)
1
2
3
4
5
6
7
8j = 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
虽然所有的答案都很受欢迎,但仅代码答案往往不能很好地解释主题。请添加一些上下文。
这是Python 3中的解决方案,不区分大小写:
1
2
3
4
5
6
7
8s = '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)
我不确定这是否已经看过了,但我认为这是一个"一次性"一词的解决方案:
1
2
3
4
5
6for i in xrange(len(word)):
if word[:len(term)] == term:
count += 1
word = word[1:]
print count
你所搜索的单词是单词,而term是你要查找的单词
1
2
3import re
d = [m.start() for m in re.finditer(seaching, string)]
print (d)
这将查找字符串中找到的子字符串的次数并显示索引。
在re.finditer中输入re d d = [m.start()for m(st3,st2)] #finding在字符串中找到子字符串的次数并显示索引print(d)
1
2
3
4
5
6
7
8
9
10
11
12
13string="abc"
mainstr="ncnabckjdjkabcxcxccccxcxcabc"
count=0
for i in range(0,len(mainstr)):
k=0
while(k
if(string[k]==mainstr[i+k]):
k+=1
else:
break
if(k==len(string)):
count+=1;
print(count)
也许你可以详细说明这个解决方案与另一个解决方案有何不同,是否有一个特殊情况可以解决?
虽然此代码可以回答这个问题,但提供有关如何和/或解决问题的原因的其他背景将提高答案的长期价值。
1
2
3
4
5
6
7
8
9
10my_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("
").split("").count("string")
Count = my_string.lower().strip("
").split("").count("strings")
print("The number of occurance of word String is :" , Count)
print("The number of occurance of word Strings is :" , Count)
您可以使用startswith方法:
1
2
3
4
5
6def count_substring(string, sub_string):
x = 0
for i in range(len(string)):
if string[i:].startswith(sub_string):
x += 1
return x
因为2个以上的其他人已经提供了这个解决方案,所以要冒险。我甚至赞成其中一个。但我的新手可能是最容易理解的。
1
2
3
4
5
6
7
8
9def 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
以下逻辑适用于所有字符串和特殊字符
1
2
3
4
5
6
7def 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"))
如果要计算所有子字符串(包括重叠),请使用此方法。
1
2
3
4
5import re
def count_substring(string, sub_string):
regex = '(?='+sub_string+')'
# print(regex)
return len(re.findall(regex,string))
对于带空格分隔的简单字符串,使用Dict会非常快,请参阅下面的代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19def 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')