挑战说明:

如果列出低于10的所有自然数,它们是3或5的倍数,则得到3、5、6和9。这些倍数的总和为23。

找到1000以下的3或5的所有倍数之和。 />
total_sum = 0
for i in range(1000):
    if (i%3 == 0 or i%5 == 0):
        total_sum = total_sum+i
print total_sum


评论

在range(1000)内是否真的表示1 ... 999(请记住问题要求低于1000)

#1 楼


total_sum = 0
for i in range(1000):
    if (i%3 == 0 or i%5 == 0):
        total_sum = total_sum+i
print total_sum  



您应该在数字,变量和运算符之间增加一些水平的空间,在它们之间增加一些水平的空间,以提高可读性。

total_sum = 0
for i in range(1000):
    if (i % 3 == 0 or i % 5 == 0):
        total_sum = total_sum + i
print total_sum  


由于未明确定义包含0的自然数,因此您也可以使用range()函数的两参数形式并指定start参数,如

total_sum = 0
for i in range(1, 1000):
    if (i % 3 == 0 or i % 5 == 0):
        total_sum = total_sum + i
print total_sum  


评论


\ $ \ begingroup \ $
我不确定我是否理解你的第二点,而我不太确定OP是否能够理解。例如,您提到了一个start参数,但是下面的代码示例不包含该单词。也许您可以更清楚地说明您的意思。
\ $ \ endgroup \ $
–mkrieger1
2015年9月3日13:38在

\ $ \ begingroup \ $
现在更清楚了吗?
\ $ \ endgroup \ $
– Heslacher
2015年9月3日下午13:39

\ $ \ begingroup \ $
一点。我想让我烦恼的是,您已经编写了“开始参数”,就好像它们是几个“开始参数”一样,您可以选择其中一个。但您指的是范围函数的第一个参数,称为“开始”。理想情况下,还会有一个文档链接,以便可以立即看到该函数的不同形式。
\ $ \ endgroup \ $
–mkrieger1
2015年9月3日下午13:49

\ $ \ begingroup \ $
我不使用python,我只搜索了range(),发现可以使用可选的start参数。我将改写我的答案。
\ $ \ endgroup \ $
– Heslacher
2015年9月3日在13:52



\ $ \ begingroup \ $
请注意,由于自然数经常被定义为包括0,因此我认为除了“效率”的提高外,最后的变化实际上不是改善。
\ $ \ endgroup \ $
–porglezomp
2015年9月3日16:20

#2 楼

您完全不需要迭代即可解决此问题。

考虑一下;从1到n的所有数字的总和等于n *(n + 1)/ 2。同样,小于n的所有数字之和除以d等于d小于n / d的所有数字之和。

所以小于1000的所有数字的总和除以3

同样,小于1000的所有数字的总和除以5 is

3*floor(999/3)*(floor(999/3)+1)/2


但是,将两个数字相加会超出计算范围。由于将3和5相除的数字将被计数两次。将3和5相除的数字恰好是对3*5/gcd(3,5)=15/1=15进行除数。 br />所以最终结果是小于1000的所有数字之和除以3或5等于:
5*floor(999/5)*(floor(999/5)+1)/2


评论


\ $ \ begingroup \ $
可以使用整数除法运算符//代替调用floor。同样,相关的概念对于记住包含-排除原理非常有用。
\ $ \ endgroup \ $
– Jaime
2015年9月3日15:33



\ $ \ begingroup \ $
我了解到,这是解决我所解决的大部分(全部)Euler问题的技巧。他们通常有一个相当明显的蛮力解决方案,然后是一个基于数学算法的简单直接的“更模糊”的解决方案。
\ $ \ endgroup \ $
– Peter Tirrell
2015年9月3日于20:19

#3 楼

定义一个函数以解决更一般的问题: >
def divisible_by_under(limit, divs):
    return (i for i in  range(limit) if any(i % div == 0 for div in divs))


评论


\ $ \ begingroup \ $
@CoolGuy也应该与pithon 2一起使用
\ $ \ endgroup \ $
– Caridorc
2015年9月3日15:34

\ $ \ begingroup \ $
嗯。我以为在打印件上加上括号会引起一些错误...
\ $ \ endgroup \ $
– Spikatrix
2015年9月3日15:39

\ $ \ begingroup \ $
@CoolGuy几乎..在python 3中未使用parens打印是错误
\ $ \ endgroup \ $
– Caridorc
2015年9月3日,15:53

\ $ \ begingroup \ $
@CoolGuy在任何版本的Python中,不必要的括号都可以,并且它们不需要任何周围的空格。
\ $ \ endgroup \ $
–isaacg
2015年9月5日下午0:04

#4 楼

您可以使用列表推导来节省几行,但与您的完全相同:

print(sum([i for i in range(1000) if i%3==0 or i%5==0]))


评论


\ $ \ begingroup \ $
我最喜欢这种形式,只是想补充一下,sum函数也需要一个生成器表达式,因此您不需要方括号:print(sum(i for i in range(1000)if i %3 == 0或i%5 == 0))
\ $ \ endgroup \ $
–yoniLavi
2015年9月3日下午22:37

#5 楼

您无需完全输入以下内容:取运算符左边的内容,然后加上右边的结果。 +=将立即创建存储在内存中的数字的完整列表,而for i in xrange(1000)是一个生成器,可根据需要生成每个数字。性能差异对大范围有用,但通常是保持的好习惯。

评论


\ $ \ begingroup \ $
但是要小心,因为xrange对Python 3是不好的建议。
\ $ \ endgroup \ $
– Nayuki
2015年9月4日下午0:47

\ $ \ begingroup \ $
@Nayuki,为什么它是个坏建议的链接会有所帮助。
\ $ \ endgroup \ $
–通配符
16年11月18日在3:49

\ $ \ begingroup \ $
@Wildcard Python 3没有xrange,因为range已经是一个生成器。我想这就是他们的意思。
\ $ \ endgroup \ $
–SuperBiasedMan
16-11-18在9:49



#6 楼

此代码效率极低。使用一些基本的数学运算,我们可以将运行时间减少到恒定的时间复杂度。对于任何n(在这种情况下为1000),我们可以预测< n的数量并可以被3或5整除: />被5整除的数字:lowerbound(n / 5)

然后可以使用eulers公式预测被3或5整除的所有数字的总和:到nn(n + 1)/2。因此,所有可被3整除的数字n的总和为: (将所有数字的总和除以3,将所有数字的总和除以5)。由于3和5是素数,因此所有可被3和5整除的数字都是15的倍数。

int div_3 = (n / 3)
int sum_div_3 = div_3 * (div_3 + 1) / 2 * 3


我无法提供python代码。