2013-12-08 122 views
2

我需要编写一个程序,总结所有可在100到2000范围内除以3的整数。我甚至不知道从哪里开始,到目前为止我写了一小段代码,这是不正确的。总结范围内的所有整数()

for x in range(100, 2001, 3): 
     print(x+x) 

任何帮助非常感谢!

+2

如果这更像是“发明一种算法”的作业,提示可能就足够了:一个数字可以被三整除,以防单个组件总和为可被三整除的数字(例如948可以被3整除,因为9 + 4 + 8 = 21可以被3整除,等等)。 –

回答

6

使用发电机表达和功能在这里:

res = sum(x for x in range(100, 2001) if x % 3 == 0) 

这是不言自明的代码:你将所有数字从100到2000,包括在内,可以被3整除。

+2

你可以删除'[]' - 不需要物化列表来计算总和。 – ThiefMaster

+0

@ThiefMaster所以它会成为一个列表生成器,对吧? – aga

+0

@ThiefMaster如果它没有实现列表,它传递的总和值是多少? –

0

有一个sum function

>>> sum(filter(lambda x: x % 3 == 0, range(100, 2000))) 
664650 

但是,这是更好的:

>>> sum(x for x in range(100, 2000) if x % 3 == 0) 
664650 
+3

错误,因为你总结的数字不能被3整除。 –

+1

100不能被3整除,所以这是不正确的 – Max

+0

其实它没有错,因为有这样的功能。但我会编辑帖子,谢谢,我的不好 – Deck

11

既然你知道在这个范围内的第一个数字是由3整除的是102,你可以做到以下几点:

解决方案:

>>> sum(range(102, 2001, 3)) 
664650 

,使之成为一个强大的功能:

def sum_range_divisible(start, end, divisor): 
    while start % divisor != 0: 
     start += 1 
    return sum(range(start, end, divisor)) 

使用它:

>>> sum_range_divisible(100, 2001, 3) 
664650 

注:

这里的好处是,你不必检查在全范围内的每个数字,因为你是3,每次跳跃。


时间:

我已经超时了不同的解决方案,矿山和aga's

>>> import timeit 
>>> timeit.Timer('sum(range(102, 2001, 3))').repeat() 
[9.516391893850312, 9.49330620765817, 9.508695564438462] 
>>> timeit.Timer('sum(x for x in range(100, 2001) if x % 3 == 0)').repeat() 
[134.757627812011, 134.46399066622394, 138.34528734198346] 

结论:

我的回答是快了的因素14

+0

对于'3'来说并不重要,但是'while start%divisor!= 0:start + = 1'对于较大的'divisor'并不好。也许'start + =(-start%abs(divisor))'。 –

+0

@InbarRose不需要我的解决方案和你的时间 - 很明显,数字的简单求和比遍历比你的三倍长的范围要快得多,只过滤那些可以被三个w/o余数并对它们进行求和。 :)你已经想出了一个优雅的解决方案,为此+1。 – aga

+0

@InbarRose我喜欢你的解决方案,但是aga的解决方案包含一个我打算使用的循环。 – maku

0
sum(filter(lambda l : l%3 ==0, range(100,2001))) 
+1

请不要使用lambda过滤器。代之以使用列表理解/生成器表达式更好。 – ThiefMaster

+0

我不认为我们应该在这里讨论lambda的新章节,由于我使用它们的某些原因,关于lambda的讨论已经很多。总之,请转到此链接https://mail.python.org/pipermail/python-dev/2006-February/060415.html – devil00

1

这是一个封闭的公式。

如果(u_i)是由它的第一项U_0及其共同差r,则的(u_i)的n个第一项的总和所定义的序列是:

\frac{n(u_0 + u_{n-1})}{2}

编辑:我有使这个小小的video视觉解释。

A popular anecdote将此公式归于年轻的Johann Carl Friedrich Gauss。

在你的情况:

  • U_0 = 102
  • U_ {N-1} = 1998
  • N =(1998 - 102)/ 3 + 1 = 633

因此,总和为(633 *(102 + 1998))/ 2 = 664650.

作为通常的range参数的Python函数startstopstep

def arithmetic_series(start, stop, step): 
    number_of_terms = (stop - start) // step 
    sum_of_extrema = start + (stop - step) 
    return number_of_terms * sum_of_extrema // 2 

在你的情况下,呼叫将是:

arithmetic_series(102, 2001, 3) 

的复杂度为O(1),而不是为O(n),所以毫不奇怪:

%timeit sum(range(102, 2001, 3)) 
100000 loops, best of 3: 17.7 µs per loop 

%timeit arithmetic_series(102, 2001, 3) 
1000000 loops, best of 3: 548 ns per loop