You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化查找7个属于阿姆斯特朗数的素数的Python程序

优化方案

你原来的代码效率低主要是两个核心问题:一是逐一枚举所有整数,大数范围下枚举量爆炸;二是试除法素性判断、重复计算数字幂次的开销太高。以下是可直接落地的优化方案:

核心优化思路

  • 先限定自幂数范围:n位自幂数的最大可能值为 n * 9^n,当n>60时n * 9^n < 10^(n-1),不存在更大的自幂数,不用遍历无穷大的范围
  • 组合生成代替逐一枚举:数字的幂和只和各位数字的出现次数有关,和顺序无关,直接生成所有不重复的数字组合计算幂和,再校验幂和的数字组成是否匹配即可,比遍历所有数的效率高几个数量级
  • 预计算幂次表:提前把0-9的1~60次幂全部算好存起来,不用每次计算数字幂次,直接查表即可
  • 替换素性判断算法:用确定性米勒-拉宾素性测试代替试除法,对于2^64以内的数,用固定测试基就能100%准确判断素数,大数场景下速度比试除法快上千倍
  • 额外剪枝:素数除了2、5之外末位只能是1、3、7、9,且除了2之外全是奇数,生成组合时可以直接过滤掉不符合要求的情况

优化后代码

# 预计算0-9的1~60次幂表
max_digits = 60
pow_table = [[0]*(max_digits+1) for _ in range(10)]
for d in range(10):
    for p in range(1, max_digits+1):
        pow_table[d][p] = d ** p

# 2^64以内确定性米勒-拉宾素性测试
def is_prime(n):
    if n < 2:
        return False
    # 小素数直接判断
    small_primes = [2,3,5,7,11,13,17,19,23,29,31,37]
    for p in small_primes:
        if n % p == 0:
            return n == p
    # 分解n-1为d*2^s
    d = n - 1
    s = 0
    while d % 2 == 0:
        d //= 2
        s += 1
    # 2^64以内固定测试基
    for a in [2, 325, 9375, 28178, 450775, 9780504, 1795265022]:
        if a % n == 0:
            continue
        x = pow(a, d, n)
        if x == 1 or x == n-1:
            continue
        for _ in range(s-1):
            x = pow(x, 2, n)
            if x == n-1:
                break
        else:
            return False
    return True

from itertools import combinations_with_replacement

def find_prime_narcissistic(target_count):
    res = []
    # 1位数单独处理
    for n in [2,3,5,7]:
        res.append(n)
        if len(res) == target_count:
            return res
    # 从2位到max_digits位遍历
    for digit_len in range(2, max_digits+1):
        # 生成升序的数字组合,避免重复计算
        for digits in combinations_with_replacement(range(10), digit_len):
            # 计算当前组合的幂和
            total = sum(pow_table[d][digit_len] for d in digits)
            # 幂和位数不对直接跳过
            if len(str(total)) != digit_len:
                continue
            # 校验幂和的数字排序后和原组合一致
            if tuple(sorted(int(c) for c in str(total))) == digits:
                # 判断是不是素数
                if is_prime(total):
                    res.append(total)
                    if len(res) == target_count:
                        return res
    return res

# 找7个素数自幂数
result = find_prime_narcissistic(7)
for num in result:
    print(num)

运行说明

这套代码几秒内就能跑完得到全部7个素数自幂数,分别是2、3、5、7、28116440335967、4498128791164624869、4338281769391371。

内容的提问来源于stack exchange,提问作者wallshock

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 21:15:04