1. 程式人生 > 其它 >能被3或5整除的1000以內的數字和(等差數列求和方式)

能被3或5整除的1000以內的數字和(等差數列求和方式)

首先想到的肯定是這樣

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整除的數之和。