如何正确识别 1 到 10000 范围内的所有阿姆斯特朗数

1次阅读

本文详解 python 中阿姆斯特朗数(水仙花数)的完整判定逻辑,指出常见错误——固定使用指数 3 导致仅输出三位数结果,并提供可适配任意位数的通用实现方案。

本文详解 python 中阿姆斯特朗数(水仙花数)的完整判定逻辑,指出常见错误——固定使用指数 3 导致仅输出三位数结果,并提供可适配任意位数的通用实现方案。

阿姆斯特朗数(Armstrong number),又称自恋数(narcissistic number)或水仙花数(narcissistic number 的中文俗称),其数学定义为:一个 n 位正整数,等于其各位数字各自 n 次方的和。例如:

  • 153 是 3 位数 → 1³ + 5³ + 3³ = 1 + 125 + 27 = 153 ✅
  • 9474 是 4 位数 → 9⁴ + 4⁴ + 7⁴ + 4⁴ = 6561 + 256 + 2401 + 256 = 9474 ✅

而原代码中始终使用 rem ** 3,本质上只在检测 三位阿姆斯特朗数,因此输出止步于 407(最后一个三位阿姆斯特朗数),漏掉了 1634、8208、9474 等四位数解,以及 1、2……9 这些一位数解(因 1¹ = 1, 2¹ = 2 ……均成立)。

✅ 正确实现:动态计算位数并匹配指数

关键在于:指数必须等于数字的位数,而非硬编码为 3。可通过 len(str(num)) 获取位数(简洁可靠,适用于正整数),再在循环中对每位数字进行对应次幂运算:

def check_armstrong(num):     if num < 0:         return False     temp = num     num_digits = len(str(num))  # 动态获取位数,如 9474 → 4     total = 0     while temp > 0:         digit = temp % 10         total += digit ** num_digits  # 每位数字的 num_digits 次方         temp //= 10     return total == num  # 查找 1~10000 内所有阿姆斯特朗数 armstrong_numbers = [x for x in range(1, 10001) if check_armstrong(x)] print(armstrong_numbers) # 输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474]

? 提示:range(1, 10001) 确保包含 10000(虽其本身不是阿姆斯特朗数,但边界需明确);1 至 9 均满足 d¹ = d,故全部合法。

⚠️ 注意事项与优化建议

  • 避免字符串转换开销? 若追求极致性能(如超大范围扫描),可用数学方法求位数(如 int(math.log10(num)) + 1),但需单独处理 num == 0;对 1~10000 场景,len(str(num)) 更清晰、安全、可读性强。
  • 负数与零处理 :阿姆斯特朗数定义通常限定为 正整数,函数中建议显式排除 num <= 0(如上例已加 if num < 0 防御)。
  • 效率考量:本算法时间复杂度为 O(d × log₁₀n),其中 d 为位数,对万级范围完全无压力;若扩展至百万 / 千万级,可考虑预计算各数字各次幂表(如 pow_table[digit][power])减少重复幂运算。

✅ 总结

判断阿姆斯特朗数的核心是「位数即指数」。摒弃固定指数(如 **3),改用 len(str(num)) 动态获取位数,即可准确识别任意位数下的所有解。运行修正后代码,你将得到完整的 16 个阿姆斯特朗数(1–10000 范围内),真正覆盖定义本质——这才是健壮、可扩展的编程实践。

星耀云
版权声明:本站原创文章,由 星耀云 2026-03-21发表,共计1371字。
转载说明:转载本网站任何内容,请按照转载方式正确书写本站原文地址。本站提供的一切软件、教程和内容信息仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。
text=ZqhQzanResources