我正在为this problem.
编码Maggu刚刚加入了游戏学校。他的老师教他A,a,B,b,C,c。他对这些字母非常着迷,现在他只关注那些只包含这些字母的字符串。但正如我所说,他是一个小家伙,他不能单独计算这些子串的数量。找出这样的字符串的数量。
def substrings(string):
for size in range(1, len(string)+1):
for index in range(len(string)-size+1):
yield string[index:index+size]
l = []
for x in range(int(raw_input())):
l.append(raw_input().lower())
not_ = 'defghijklmnopqrstuvwxyz'
for string in l:
count = 0
for substr in substrings(string):
if all(letter not in substr for letter in not_):
count = count + 1
print(count)
我意识到我们可以将问题减少到小写。我编写了代码,但对大字符串效率不高。而且大的意思是特别大的字符串。我已经意识到substrings
函数占用了大量的时间。如何减少substrings
功能的时间消耗?我可以用其他代码替换它吗?
感谢。
答案 0 :(得分:3)
这是指数的原因是因为你为不同的窗口长度迭代相同的字符串(最多为len(字符串))。这是正则表达式的一个工作,它只需要对你的字符串进行一次传递,以便至少连续一次找到包含字母a,b,c,A,B和C的任何序列。
找到这些序列后,您可以计算它们的算术级数,以计算每个序列包含的子串数。要理解为什么我们必须使用算术级数,请考虑我们在大字符串中找到序列'abc'。该序列的实际子串是'a','ab','abc','b','bc'和'c'。基本上,对于长度为n的字符串,我们可以从第一个字母开始构造n个子字符串,从第二个字母开始构造n-1个子字符串,......和从最后一个字母开始的1个子字符串。
import re
def count_substrings(string):
found = re.findall('[a-cA-C]+', string)
count = 0
for f in found:
length = len(f)
count += length * (length + 1) / 2
return count
对于链接中显示的示例
>>> strings = ['AXa', 'ABC', 'AXBC', 'AaBbCc', 'XxYyZz']
>>> for s in strings:
... print(count_substrings(s))
2
6
4
21
0
如果您想实施re.findall()
自己做的事情,可以尝试以下方法。
found = []
substring = ''
for s in string:
if s in 'abcABC':
substring += s
else:
# if we had a sequence going, it just ended, so add it to our found list
if substring:
found.append(substring)
substring = ''
# make sure to append the last sequence we had been working on
if substring:
found.append(substring)