首先想到的肯定是這樣
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整除的數之和。