完整源代码项目地址,关注博主私信'源代码'后可获取
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