【自幂数】一个神奇的数字

自幂数是一个非常有趣和神奇的数字概念。在数学中,自幂数也被称为阿姆斯特朗数(Armstrong Number)或自恋数(Narcissistic Number)。

什么是自幂数?

自幂数是一个 n 位数,它的每个数字的 n 次幂相加等于该数字本身。更具体地说,对于一个 n 位数 x,如果满足以下公式:

x = d 1 n + d 2 n + d 3 n + . . . + d n n x = d1^n + d2^n + d3^n + ... + dn^n x=d1n+d2n+d3n+...+dnn

其中,d1, d2, d3, …, dn 是 x 的各个位上的数字。如果上述等式成立,那么 x 就是一个自幂数。

例如,153 是一个自幂数,因为 1 3 + 5 3 + 3 3 = 153 1^3 + 5^3 + 3^3 = 153 13+53+33=153

当然不同的自幂数还有其优雅的叫法:

  • 独身数:[1, 2, 3, 4, 5, 6, 7, 8, 9]
  • 水仙花数:[153, 370, 371, 407]
  • 四叶玫瑰数:[1634, 8208, 9474]
  • 五角星数:[54748, 92727, 93084]
  • 六合数:[548834]
  • 北斗七星数:[1741725, 4210818, 9800817, 9926315]
  • 八仙数:[24678050, 24678051, 88593477]
  • 九九重阳数:[146511208, 472335975, 534494836, 912985153]
  • 十全十美数:[4679307774]

下面介绍几种求自幂数的算法:

  1. 第一种是最直接的求法,逻辑简单就是直接根据自幂数的定义暴力求解,缺点就是速度慢,内存消耗大
private static ArrayList findArmstrongNumbers(int t) {
    ArrayList ints = new ArrayList();
    double[] a = new double[t];
    int result = 0;
    double low = Math.pow(10, t - 1);
    double high = Math.pow(10, t);

    for (double i = low; i < high; i++) {
        for (int j = 0; j < t; j++) {
            a[j] = (i / (Math.pow(10, j))) % 10;
            result += Math.pow(a[j], t);
            a[j] = 0;
            if (result > i) {
                break;
            }
        }
        if (i == result) {
            ints.add(i);
        }
        result = 0;
    }
    return ints;
}
  1. 第二种是利用steam流简化代码书写,可读性更高,运行效率也能提高不少
private static List<Integer> selfExponent(int t) {
    List<Integer> ints = new ArrayList<>();
    double low = Math.pow(10, t - 1);
    double high = Math.pow(10, t);

    for (double i = low; i < high; i++) {
        int finalI = (int) i;
        int sum = String.valueOf(finalI)
                .chars()
                .map(Character::getNumericValue)
                .map(n -> (int) Math.pow(n, t))
                .sum();
        if (finalI == sum) {
            ints.add(finalI);
        }
    }
    return ints;
}
  1. 第三种在第二种的基础上,摒弃了冗余的重复计算并加入了并行处理进一步提高了代码运行效率
private static List<Integer> selfExponentPlus(int t) {
    List<Integer> ints = new LinkedList<>();
    int low = (int) Math.pow(10, t - 1);
    int high = (int) Math.pow(10, t);

    IntStream.range(low, high)
            .parallel()
            .filter(i -> {
                int sum = String.valueOf(i)
                        .chars()
                        .map(Character::getNumericValue)
                        .map(n -> (int) Math.pow(n, t))
                        .sum();
                return i == sum;
            })
            .forEach(ints::add);
    return ints;
}
  1. 测试代码
public class SelfPowerNumber1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> result = new ArrayList<>();
        List<Integer> numResult = new ArrayList<>();
        int exp = -1;
        while (true) {
            System.out.print("请输入您想要求取的自幂数维度:");
            exp = sc.nextInt();
            if (exp == 2) {
                System.out.println("OVER!");
                break;
            }
            numResult = selfExponentPlus(exp);
            result.addAll(numResult);
            System.out.println(numResult.toString());
        }
    }
}

测试结果
在这里插入图片描述

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值