理解Python字符串中的重复计数

理解Python字符串中的重复计数,python,string,Python,String,我有一个挑战:解决问题。我一直在尝试解决这个挑战,但由于记忆故障而失败。我无法避免这种情况,因为HackerRank平台不支持我的解决方案。可能是32位平台 我有这个解决方案,它对于长度较小的问题非常有效,但我一直在研究这个问题,以减少内存使用 我的代码: def repeatedString(s, n): if(s != 'a'): return len([x for x in (s*n)[:n] if x == 'a']) return n def repeated

我有一个挑战:解决问题。我一直在尝试解决这个挑战,但由于记忆故障而失败。我无法避免这种情况,因为HackerRank平台不支持我的解决方案。可能是32位平台

我有这个解决方案,它对于长度较小的问题非常有效,但我一直在研究这个问题,以减少内存使用

我的代码:

def repeatedString(s, n):
   if(s != 'a'):
     return len([x for x in (s*n)[:n] if x == 'a'])

   return n
def repeatedString(s, n):
 L = len(s)
 return (s.count('a') * (n//L) + s[:n % L].count('a'))
def repeatedString(s, n):
    L = len(s)
    return (s.count('a') * (n//L) + s[:n % L].count('a'))
现在,对于长度非常大的输入和字符串,这会抛出
内存错误

我对它进行了研究,看到了一些意见书,发现了这一点

排行榜中的正确解决方案:

def repeatedString(s, n):
   if(s != 'a'):
     return len([x for x in (s*n)[:n] if x == 'a'])

   return n
def repeatedString(s, n):
 L = len(s)
 return (s.count('a') * (n//L) + s[:n % L].count('a'))
def repeatedString(s, n):
    L = len(s)
    return (s.count('a') * (n//L) + s[:n % L].count('a'))

就这样!我被这个解决方案弄糊涂了,以至于我能弄清楚到底发生了什么以及如何发生。有人能告诉我上述正确的解决方案是如何工作的吗?我对python还不熟悉,并尽我最大的努力在竞争性的编码上弄脏我的手。谢谢大家!

您的函数正在抛出内存错误,因为您正在构造一个长度为输入参数n的字符串

n可以是10^12,这导致字符串的最大长度为1000亿个字母,这意味着您正在创建的字符串的内存大小可能为1TB(可能更大,具体取决于字符串的编码)

所以必须有另一种方法来计算该大小字符串中的a的数量,对吗?

是的(这就是正确答案与您的解决方案不同的原因)


1。首先我们得到输入字符串的长度。

L = len(s)
例如,“abcde”的长度为5


2。然后,我们计算s中“a”的数量。

s.count('a')
(n//L)
s.count('a') * (n//L)

3。接下来,我们想知道在到达长度为n的字符串之前,s作为一个整体重复了多少次。

s.count('a')
(n//L)
s.count('a') * (n//L)
调用
/
运算符,得到一个整数。例如,对于s='abcde'和n=14,
n//L
等于2


4。将s中的“a”数乘以s可以放入长度为n的字符串的次数。

s.count('a')
(n//L)
s.count('a') * (n//L)

5。我们几乎完成了,但以我们为例,仍然缺少一些东西abcde'可以在长度为n的字符串中重复两次,但在我们的示例“abcd”中,仍剩下4个字符。

s.count('a')
(n//L)
s.count('a') * (n//L)
在这里,我们使用
s[:n%L]
,或者在我们的示例中使用
s[:14%5]
s[:4]
,从s构造剩余字符串,结果是
'abcd'

然后我们用
s[:n%L]计算这个字符串中“a”的数量。计数('a')


6。将所有这些加在一起,我们就可以在您的答案中找到函数:

def repeatedString(s, n):
   if(s != 'a'):
     return len([x for x in (s*n)[:n] if x == 'a'])

   return n
def repeatedString(s, n):
 L = len(s)
 return (s.count('a') * (n//L) + s[:n % L].count('a'))
def repeatedString(s, n):
    L = len(s)
    return (s.count('a') * (n//L) + s[:n % L].count('a'))

因此,这两种算法之间的关键区别在于,在您的原始算法中,您使用了
s*n
,这实际上会尝试在内存中构建大量字符串。这就是为什么会出现内存错误

第二种算法本质上说,“对于长度为
X
的字符串
s
,重复到长度
N
s
将适应
M
N//X
次,可能还有一块
s
剩余部分(除法余数)

例如,如果您的字符串为
aab
(X=3)且N为10,则您知道该字符串将适合3次,剩余1个字符

因此,假设s中有2个字母
a
,您知道前9个字符中将有
2*3
a。现在您需要处理余数。最后一个字符(余数)将是
s
的第一个字符

在第二种解决方案中,
s.count('a')*(n//L)+s[:n%L]。count('a')
是这两部分

s.count('a')*(n//L)
-在我的示例中,这给出了
2*3


s[:n%L]。计数('a')
-这将为您提供“余数”部分。

传递给函数的参数是什么?我猜第一个是字符串,另一个是?长度。要了解更多问题,您可以参考hackerrank@AkshayNevrekar上的问题链接。谢谢Nico,您有很好的简报技巧。再次感谢:)不用担心!很高兴提供帮助