chars1
/chars2
中出现在 s
中的字符数
这很有意义,因为你使用了带有 if
条件的递增。由于 if
不在循环中,您可以递增一次。
现在我们可以将生成器展开为 for
循环。这将解决问题的一部分并生成 0/6
:
<b>for c in chars1:
if c in s:
counter1 += 1</b>
<b>for c in chars2:
if c in s:</b>
counter2 += 1
然而,这仍不是非常高效的:它需要 O(n) 的最坏情况来检查字符是否在字符串中。您可以首先构造一个包含字符串中字符的 set
,然后执行查找操作(通常平均情况下为 O(1)):
def error_printer(s):
<b>sset = set(s)</b>
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
counter1 = 0
counter2 = 0
for c in chars1:
if c in <b>sset</b>:
counter1 += 1
for c in chars2:
if c in <b>sset</b>:
counter2 += 1
print(str(counter2) + "/" + str(counter1))
现在我们已经提高了效率,但是它仍然不够优雅: 它需要大量的代码,而且还需要检查代码才能知道它的作用。我们可以使用sum(..)
结构来计算满足某些约束条件的元素数量,例如:
def error_printer(s):
sset = set(s)
chars1 = "abcdefghijklm"
chars2 = "nopqrstuvwxyz"
<b>counter1 = sum(c in sset for c in chars1)
counter2 = sum(c in sset for c in chars2)</b>
print(str(counter2) + "/" + str(counter1))
这会产生0/6
的结果,因为在s
中有六个字符在[A-M]
范围内出现,而在s
中没有任何一个字符在[N-Z]
范围内出现。
s
中出现在char1
/char2
中的字符数
根据问题的主体部分,您想要计算在两个不同范围内出现在s
中的字符数。
另一个相关问题是计算在char1
/char2
中出现的字符数。在这种情况下,我们只需要交换循环:
def error_printer(s):
chars1 = <b>set(</b>"abcdefghijklm"<b>)</b>
chars2 = <b>set(</b>"nopqrstuvwxyz"<b>)</b>
counter1 = sum(c in <b>chars1</b> for c in <b>s</b>)
counter2 = sum(c in <b>chars2</b> for c in <b>s</b>)
print(str(counter2) + "/" + str(counter1))
这将产生
0/14
的结果,因为字符串
s
中有14个字符在
[A-M]
范围内(如果
'a'
在
s
中出现两次,则计算两次),而
s
中没有字符在
[N-Z]
范围内。
使用范围检查
由于我们正在使用
范围,因此我们可以使用比较而不是元素检查,并通过两个比较检查使其运行,如下所示:
def error_printer(s):
counter1 = sum(<b>'a' <= c <= 'm'</b> for c in s)
counter2 = sum(<b>'n' <= c <= 'z'</b> for c in s)
print(str(counter2) + "/" + str(counter1))
(c in s) for c in chars1
是一个生成器,它恰好会求值为真,因此counter1 += 1
总是会被执行。但是由于这是一个 if 语句 而不是循环,所以它只会被执行一次。 - poke0 / 14
还是0 / 6
。你只是在迭代charsX
并计算这些项。 - AChampion