案例解析

您所在的位置:网站首页 八仙齐打一个数字 案例解析

案例解析

2024-06-03 12:04| 来源: 网络整理| 查看: 265

浏览 112 扫码 分享 2023-11-22 14:36:00 输入格式输出格式

描述自幂数是指一个 n 位数,它的每位上的数字的 n 次幂之和等于它本身,例如:13 + 53+ 3**3 = 153,编程寻找并输出 n 位的自幂数,n 由用户输入,每行输出一个数字。n为1时,自幂数称为独身数。显然,0,1,2,3,4,5,6,7,8,9都是自幂数。n为2时,没有自幂数。n为3时,自幂数称为水仙花数,有4个n为4时,自幂数称为四叶玫瑰数,共有3个n为5时,自幂数称为五角星数,共有3个n为6时,自幂数称为六合数, 只有1个n为7时,自幂数称为北斗七星数, 共有4个n为8时,自幂数称为八仙数, 共有3个n为9时,自幂数称为九九重阳数,共有4个n为10时,自幂数称为十全十美数,只有1个

输入格式

输入一个大于或等于 3 且小于 7 的正整数 n

输出格式

输出 n 位的自幂数,每行一个数

我们先看题目:自幂数是指一个 n 位数,它的每位上的数字的 n 次幂之和等于它本身,编程寻找并输出 n 位的自幂数,n 由用户输入,每行输出一个数字。

1.所有的n位数是一个整数数列 ,可以由range()函数获得,,例如 n = 3时,可产生[100,1000)之间的整数数列,下面用 num 表示其中一个数。

for num in range(10 ** (n-1),10 ** n):

2.整数 num 每位上的数字的获取可以用 while 循环的方法,当num 值不为0时进入循环,循环中用num对10 取模的方法获得最后一位数字。因后面需要比较获得的加和与 num 是否相等,此处先将num的值用其他名字保存一份,此处用temp,程序中用temp获取每位上的数字。

while temp != 0: last = temp % 10 # 获得末位上的数字 temp = temp // 10 # 获取去除末位后的数字 数字的n次幂可以用 last ** n 或pow(last,n)获得,因需要累加,所以在每测试一个新的 n位数时,要先设一个累加初值0: result = 0result = result + last ** n

4.n次幂之和可以用循环累加的方法获得,将每次循环获得的 last n 的结果加到一起;也可以将产生的 last n 置于列表 ls 中,再用sum(ls)获得列表中所有元素的和5.如果计算的加和等于这个数本身,则输出这个数字并换行

if result == num: # 判断相等要用 “==” print(num) # 无end参数时,输出后默认换行 # 数学方法获得每位上的数字n = int(input()) # 输入一个整数(字符串),用int()转为整数类型for num in range(10 ** (n-1),10 ** n): # 获得所有n 位整数的数列 temp = num # 将num值保存备用 result = 0 # 设置累加器初值 while temp != 0: # temp不为0时进入循环 last = temp % 10 # 获得末位上的数字 temp = temp // 10 # 获取去除末位后的数字 result = result + last ** n # 将获得的最后一位上的数字的n次方累加 if result == num: # 当累加和与num值相等时,num是自幂数,输出num print(num)

上面方法上用数学方法获得每位上的数字,在Python中可以将整数转为字符串,再用索引的方法获得每位上的数字:

# 字符串方法的应用n = int(input()) # 输入一个整数(字符串),用int()转为整数类型for num in range(10 ** (n-1),10 ** n): # 获得所有n 位整数的数列 result = 0 # 设置累加器初值 for c in str(num): # 将整数num 转为字符串并通过遍历获取其中每个字符,如'370',依次获取'3','7','0' result = result + int(c) ** n # 将获得字符转为整数并计算其n次方累加,如 3 ** if result == num: # 当累加和与num值相等时,num是自幂数,输出num print(num)

程序第5,6行可以合并用一个列表推导式完成。根据遍历获得的每位上的数的n次方构建一个列表,用sum()函数对列表元素进行求和。列表推导式的运用可以使程序更简洁。

# 列表推导式n = int(input()) # 输入一个整数(字符串),用int()转为整数类型for num in range(10 ** (n-1),10 ** n): # 获得所有n 位整数的数列 result = sum([int(c) ** n for c in str(num)]) # 将整数num 转为字符串并通过遍历获取其中每个字符,用每位上的数的n次方构建一个列表。用sum()函数得到列表元素的加和 if result == num: # 当累加和与num值相等时,num是自幂数,输出num print(num)# 列表推导式,合并计算与比较n = int(input()) # 输入一个整数(字符串),用int()转为整数类型for num in range(10 ** (n-1),10 ** n): # 获得所有n 位整数的数列 if num == sum([int(c) ** n for c in str(num)]): print(num)

考虑到程序中需要频繁的计算数字的 n次方,当自幂数位数较多时,这个计算量还是很大的,为提升效率,可以考虑一次性的计算出 0,1,2,3,4,5,6,7,8,9的n次方备用,程序中用索引的方法获取数字的 n次方,一次计算,多次使用。计算可以用循环方式,也可以用列表推导式,此处用列表推导式实现:

# 列表推导式生成0-9的n次方,程序中用索引 方式获取n = int(input()) # 输入一个整数(字符串),用int()转为整数类型ls = [x ** n for x in range(10)] # 例n 为3时 [0, 1, 8, 27, 64, 125, 216, 343, 512, 729]for num in range(10 ** (n-1),10 ** n): # 获得所有n 位整数的数列 if num == sum([ls[int(c)] for c in str(num)]): # 从列表ls中索引到序号为c的元素,构建列表,如371得到列表[27,343,1],加和为371 print(num)

程序中循环部分还可以用一个带条件的列表推导式实现,将print(num) 作为列表元素的,if作为推导的条件,代码可以合并到一起:

n = int(input()) # 输入一个整数(字符串),用int()转为整数类型ls = [x ** n for x in range(10)] # 例n 为3时 [0, 1, 8, 27, 64, 125, 216, 343, 512, 729][print(num) for num in range(10 ** (n-1),10 ** n) if num == sum([ls[int(c)] for c in str(num)])] # 获得所有n 位整数的数列

这种写法单行代码过长,逻辑上不容易理解,不推荐使用,但可以通过这样的方法学习推导式的各种用法,在训练时可以要求自己使用最精简的代码实现,在这个过程中,可以充分学习和利用python中的一些特性、方法和函数的各种用法,达到活学活用的目的。更好的写法是将问题分解成两个子问题,一个是判定一个n位数是不是自幂数;一个是遍历n位整数,输出其中的自幂数。两个函数都只有一层循环和一个分支,逻辑上更清晰,建议使用。

def armstrong_number(num, n): """接受一个正整数和一个位数为参数,判断是否是n位自幂数,返回布尔值""" total = 0 for i in str(num): total = total + int(i) ** n if num == total: return True else: return Falsedef judge_num(n): """接受一个大于2的正整数为参数,输出n位自幂数""" for num in range(10 ** (n - 1), 10 ** n): if armstrong_number(num, n): print(num)if __name__ == '__main__': m = int(input()) judge_num(m)

因每一位上数字的n次方要被 计算多次,影响 效率,我们可以考虑先将0-9的n次方计算出来存储在列表或元组中,后面通过索引的方式获得,一次计算,多次使用,从而提高程序效率。

def armstrong_number(num): """接受一个正整数为参数,判断是否是自幂数,返回布尔值""" total = 0 for i in str(num): total = total + table[int(i)] if num == total: return True else: return Falsedef judge_num(n): """接受一个大于2的正整数为参数,输出n位自幂数""" for num in range(10 ** (n - 1), 10 ** n): if armstrong_number(num): print(num)if __name__ == '__main__': m = int(input()) table = [x ** m for x in range(10)] judge_num(m)

纯数学方法可以避免字符串与整数转换过程过来的性能损失,提高效率:

def armstrong_number(num): """接受一个正整数为参数,判断是否是自幂数,返回布尔值""" total, tmp = 0, num # 累加初值和临时变量 while tmp != 0: # 若值不为0 total = total + table[tmp % 10] # tmp % 10 值为末位数字 tmp = tmp // 10 # 去除末位数字 return num == total # 相等时返回True,否则Falsedef judge_num(n): """接受一个大于2的正整数为参数,输出n位自幂数""" for num in range(10 ** (n - 1), 10 ** n): # 遍历n位数 if armstrong_number(num): # 判定是否自幂数 print(num) # 输出if __name__ == '__main__': m = int(input()) # 输入位数n table = [x ** m for x in range(11)] # 获取x的n次幂列表 judge_num(m) # 调用函数判定是否自幂数

若有收获,就点个赞吧

0 人点赞

上一篇: 下一篇:


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3