100个python算法超详细讲解:阿姆斯特朗数
1.问题描述
如果一个整数等于其各个数字的立方和,则该数称为“阿姆斯特朗
数”(亦称为自恋性数)。如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,这样最后一位就被分离出来;再次分离的
是原数的次低位,对于次低位,要想办法让其成为新数的最低位,可
采用原数n对10求商的方法,即n//10。其他位置的数据求法同上。
题目给出的数据最多三位,我们可以定义三个变量分别来存储原
数的个位、十位和百位,也可以用数组来存储,数组的长度为3。
4.确定程序框架
程序流程图如图3.6所示。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 阿姆斯特朗数
if __name__ == "__main__":
a = [0, 0, 0] # 列表a用来存储被拆分的数的个位、十位和百位
print("1000以内的阿姆斯特朗数:")
for i in range(2, 1000):
t = 0
k = i
# 按从低位到高位的顺序拆分数
while 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=" ")
6.运行结果
在中运行程序,结果如图3.7所示。
7.问题拓展
本题程序采用的是从低位到高位的顺序进行分离。下面将从高位
到低位顺序进行拆分的程序段给出,供读者参考。
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author : liuhefei
# @desc: 阿姆斯特朗数
if __name__ == "__main__":
a = [0, 0, 0] # 列表a用来存储被拆分的数的个位、十位和百位
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=" ")