自幂数是一个非常有趣和神奇的数字概念。在数学中,自幂数也被称为阿姆斯特朗数(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]
下面介绍几种求自幂数的算法:
- 第一种是最直接的求法,逻辑简单就是直接根据自幂数的定义暴力求解,缺点就是速度慢,内存消耗大
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;
}
- 第二种是利用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;
}
- 第三种在第二种的基础上,摒弃了冗余的重复计算并加入了并行处理进一步提高了代码运行效率
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;
}
- 测试代码
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());
}
}
}
测试结果