完整源代碼項目地址,關注博主私信'源代碼'后可獲取
1.問題描述 2.問題分析 3.算法設計 4.確定程序框架 5.完整的程序 6.問題拓展
1.問題描述
如果一個整數等于其各個數字的立方和,則該數稱為“阿姆斯特朗數”(亦稱為自戀性數)。如 153 = 1 3 + 5 3 + 3 3 153=1^3+5^3+3^3 153 = 1 3 + 5 3 + 3 3 ,就是一個“阿姆斯特朗數”。試編程求1000以內的所有“阿姆斯特朗數”。
2.問題分析
“阿姆斯特朗數”與3.2節中的“水仙花數”的不同在于,前者并沒有規定幾位數,從兩者的定義來看,“水仙花數”可以看作是“阿姆斯特朗數”的一個子集。對于這類問題的算法與“水仙花數”類似,需要把每一位分離出來,然后比較其立方和與原數是否相等。
3.算法設計
本題求的是1000以內滿足條件的數,從數的位數來說可以分為一位數、兩位數及三位數。這樣可以根據數的位數不同分別求出不同范圍內的“阿姆斯特朗數”,即一位數(1~9)、兩位數(10~99)和三位數(100~999)分別用一個循環語句來實現。
上述方法有其局限性,如果題目改成求1 000 000以內甚至更大范圍的話,程序里面會有多個循環,不但程序看起來煩瑣,寫起來也費事,更重要的是每個循環體做的事情都是一樣的:將數的每一位拆分。對于這種重復的事情可以考慮用循環將其簡化。對于一個數無論它的位數是多少,如果要將其拆分,要么按從低位到高位的順序,要么按從高位到低位的順序。本題按從低位到高位的順序進行拆分。
從低位到高位進行拆分,每次拆分的都是當前數的個位,可以用當前數n對10求模,即n%10,這樣最后一位就被分離出來;再次分離的是原數的次低位,對于次低位,要想辦法讓其成為新數的最低位,可采用原數n對10求商的方法,即n//10。其他位置的數據求法同上。
題目給出的數據最多三位,我們可以定義三個變量分別來存儲原數的個位、十位和百位,也可以用數組來存儲,數組的長度為3。
4.確定程序框架
程序流程圖如圖所示。
5.完整的程序
% % time
if __name__ == "__main__" : a = [ 0 , 0 , 0 ] print ( "1000以內的阿姆斯特朗數:" ) for i in range ( 2 , 1000 ) : t = 0 k = iwhile k: a[ t] = k % 10 k = k // 10 t += 1 sum = a[ 0 ] ** 3 + a[ 1 ] ** 3 + a[ 2 ] ** 3 if i == sum : print ( "%d \t " % i, end= "\n" )
1000以內的阿姆斯特朗數:
153
370
371
407
CPU times: user 4.22 ms, sys: 31 μs, total: 4.25 ms
Wall time: 3.71 ms
6.問題拓展
本題程序采用的是從低位到高位的順序進行分離。下面將從高位到低位順序進行拆分的程序段給出,供讀者參考。
% % time
if __name__ == "__main__" : a = [ 0 , 0 , 0 ] print ( "1000以內的阿姆斯特朗數:" ) for i in range ( 2 , 1000 ) : t = 0 k = 1000 while k >= 10 : a[ t] = ( i % k) // ( k // 10 ) k = k // 10 t += 1 sum = a[ 0 ] ** 3 + a[ 1 ] ** 3 + a[ 2 ] ** 3 if i == sum : print ( "%d \t" % i, end= "\n" )
1000以內的阿姆斯特朗數:
153
370
371
407
CPU times: user 4.85 ms, sys: 324 μs, total: 5.18 ms
Wall time: 4.53 ms