[英]How do I effectively generate Perfect digit-to-digit invariant numbers in Java?
A PDDI is a number such the the sum of all the digits raised to themselves is equal to the number itself. PDDI是一个数字,因此加到自己的所有数字的总和等于该数字本身。
For example, 3435 = (3^3) + (4^4) + (3^3) + (5^5) 例如3435 =(3 ^ 3)+(4 ^ 4)+(3 ^ 3)+(5 ^ 5)
The code below takes too long to check for PDDIs between one to a huge number. 下面的代码需要很长时间才能检查一个到一个巨大的PDDI。 Is there any way to make it faster? 有什么方法可以使其更快?
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0;
// We're going to try all integers between one to n.
for(int i = 1; i<=n; i++){
sum = 0;
m = i;
while(m>0){
k = m % 10;
sum = sum + (int)Math.pow(k, k);
m = m/10;
}
if(i == sum)
System.out.println(i);
}
The number from 0 to 9 to the power of 2 can be precalculated and kept in a an array. 可以预先计算从0到9到2的幂的数字并将其保存在数组中。
int powered [] = new int [10];
powered[0] = 0;
powered[1] = 1;
powered[2] = 4;
..
powered[9] = 81;
Then for each digit fech the powered number using the digit as an index to the powered array. 然后,对于每个数字,使用数字作为幂阵列的索引来获取幂数。
For example 234
would be powered[2] + powered[3] + powered[4]
例如234
将被powered[2] + powered[3] + powered[4]
This will save some math operations. 这将节省一些数学运算。
Also you could think of a multithreaded approach having N threads doing the calculations for different numbers in parallel. 您还可以想到一种多线程方法,该方法具有N个线程并行进行不同数量的计算。
Since you are using only power from 0 to 9, you could cache these values in a int[]
instead of computing Math.pow(k, k)
everytime. 由于只使用0到9的幂,因此可以将这些值缓存在int[]
而不是每次都计算Math.pow(k, k)
。 It won't improve that much but, it's a start. 不会有太大改善,但这只是一个开始。
int[] pows = new int[] {0, 1, 4, 27, 256, 3125, 46656, 823543, 16777216, 387420489 };
for (int i = 0; i < 10; ++i) {
pows[i] = (int) Math.pow(i, i);
}
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0;
// We're going to try all integers between one to n.
for(int i = 1, i<=n, i++){
sum = 0;
m = i;
while(m>0){
k = m % 10;
sum = sum + pows[k]; // use cached values here
m = m/10;
}
if(i == sum)
System.out.println(i);
}
Based on logic you may skip some iterations. 根据逻辑,您可以跳过一些迭代。 Lets take the number 281
as an example, which gives 4 + 16777216 + 1 = 16777251
, the result is above 281, so theres no changes that 282, 283, 284, ... 289 gives a number equals to 281. In such cases you may want to skip these useless iterations by manually incrementing i
. 让我们以数字281
为例,给出4 + 16777216 + 1 = 16777251
,结果在281以上,因此不会发生变化, 4 + 16777216 + 1 = 16777251
,... 289给出的数字等于281。在这种情况下您可能想通过手动增加i
来跳过这些无用的迭代。
int[] pows = new int [10];
for (int i = 0; i < 10; ++i) {
pows[i] = (int) Math.pow(i, i);
}
System.out.print("Enter the number");
Scanner s = new Scanner(System.in);
int n = s.nextInt();
int m = 0, sum = 0, k = 0, lastNumberDigit;
// We're going to try all integers between one to n.
for(int i = 1, i<=n, i++){
sum = 0;
m = i;
while(m>0){
lastNumberDigit = m; // on the last iteration, we'll get the last digit
k = m % 10;
sum = sum + pows[k]; // use cached values here
m = m/10;
}
if(i == sum) {
System.out.println(i);
} else if (sum > i) {
i += (10 - lastNumberDigit - 1); // jump to the next decade (-1 because the for will apply i++ on it)
}
}
I used this logic on decade, but you may want to extend it to hundreds or even more, but it will be much more tricky. 我在十年中使用了这种逻辑,但是您可能希望将其扩展到数百甚至更多,但是要棘手得多。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.