首先想到的肯定是这样
sum = 0
for i in range(1,1000):
if i % 3== 0 or i % 5 == 0:
sum = sum + i
print(sum)
显然虽然这个方法代码简单,也很容易理解,但是运行的效率低。
所以再想想,在1-1000中,3的倍数最小的是3,最大的是999。5的倍数最小的是5,最大的是995。3和5的倍数其中肯定有交集,而他们肯定是15的倍数,那么,15的倍数最小的是15,最大的是990。
所以,我们要的答案应该是:3的倍数和+5的倍数和-15的倍数的和(交集)。
这个结论可以扩展到跟大的范围
def sum_mod(minNumber,maxNumber):
return (maxNumber/minNumber)*(minNumber+maxNumber)/2 #等差数列求和公式
这个minNumber肯定就是3或5这个最小公因数,那么maxNumber却不好确定,比如我们在计算是使用的是 sum_mod(3,999)+sum_mod(5,995)-sum_mod(15,990)
这个maxNumber要我们指定,这样是不好的,很多代码规范里面都提到了魔鬼数字,尽量不要直接用数字。
我们希望给一个范围和最小公因数就给出这个能被最小公因数整除的的数字之和。修改一下定义的函数。把minNumber和maxNumber当成范围的上下界,加一个参数commonDivisor代表最小公因数。
def sum_mod(minNumber,maxNumber,commonDivisor):
minScope = minNumber - (minNumber % commonDivisor) + commonDivisor #给定范围中最小能被 commonDivisor 整除的数
maxScope = maxNumber - (maxNumber % commonDivisor) #给定范围中最大能被 commonDivisor 整除的数
n= maxScope/commonDivisor - minScope/commonDivisor + 1 #项数
return n* (minScope+maxScope)/2 #等差数列求和公式
这样一来,我们的输入参数就全是题目给定的值,更具有泛化性,在确定下界时为什么这么做的原因是 范围并不一定是从0开始的 ,比如求[52,141]之间能被5整除的数之和。