簡體   English   中英

如何有效地在Java中生成Perfect數位不變數字?

[英]How do I effectively generate Perfect digit-to-digit invariant numbers in Java?

PDDI是一個數字,因此加到自己的所有數字的總和等於該數字本身。

例如3435 =(3 ^ 3)+(4 ^ 4)+(3 ^ 3)+(5 ^ 5)

下面的代碼需要很長時間才能檢查一個到一個巨大的PDDI。 有什么方法可以使其更快?

    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);
    }

可以預先計算從0到9到2的冪的數字並將其保存在數組中。

int powered [] = new int [10];
powered[0] = 0;
powered[1] = 1;
powered[2] = 4;
..
powered[9] = 81;

然后,對於每個數字,使用數字作為冪陣列的索引來獲取冪數。

例如234將被powered[2] + powered[3] + powered[4]

這將節省一些數學運算。

您還可以想到一種多線程方法,該方法具有N個線程並行進行不同數量的計算。

使用緩存的值而不是Math.pow

由於只使用0到9的冪,因此可以將這些值緩存在int[]而不是每次都計算Math.pow(k, k) 不會有太大改善,但這只是一個開始。

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);
}

跳過無用的值

根據邏輯,您可以跳過一些迭代。 讓我們以數字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)
   }
}

我在十年中使用了這種邏輯,但是您可能希望將其擴展到數百甚至更多,但是要棘手得多。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM