2015-03-30 22 views
0

這裏是我輸出給定數字的素因式分解的程序。我仍然只是一個初學者,所以我知道它不是最有效的代碼。當我輸入相對較大的數字時會出現問題。如何糾正我的素數分解程序?

輸入:11輸出:11

輸入:40輸出:2 2 2 5

輸入:5427輸出:3 3 3 3 67

輸入:435843輸出:3 3 79 613

輸入:23456789輸出:無(有似乎是一個無限循環的代碼應該返回23456789,因爲它本身就是一個素數)

什麼可能CAUS這個問題?

import java.util.Scanner; 

public class PrimeFactorization { 
    public static boolean isPrime(long n) { 
     boolean boo = false; 
     long counter = 0; 
     if (n == 1) { 
      boo = false; 
     } else if (n == 2) { 
      boo = true; 
     } else { 
      for (long i = 2; i < n; i++) { 
       if (n % i == 0) { 
        counter++; 
       } 
      } 
      if (counter == 0) { 
       boo = true; 
      } 
     } 
     return boo; 
    } 

    public static void primeFactorization(long num) { 
     for (long j = 1; j <= num; j++) { 
      if (isPrime(j)) { 
       if (num % j == 0) { 
        while (num % j == 0) { 
         System.out.printf(j + " "); 
         num = num/j; 
        } 
       } 
      } 
      if (num == 1) { 
       break; 
      } 
     } 
    } 

    public static void main(String[] args) { 
     Scanner scanner = new Scanner(System.in); 
     System.out.println("Enter any number:"); 
     long num = scanner.nextLong(); 
     System.out.print("Prime factorization of your number is: "); 
     primeFactorization(num); 
     scanner.close(); 
    } 
} 
+0

請附上您的'primeFactorization'方法的其餘部分;它看起來像你只複製了最後一部分。 – rgettman 2015-03-30 18:25:00

回答

-1

無論代碼有多高效,分解大數字需要一段時間 - 只要它可能感覺計算機已掛起。考慮到你的代碼,即使是大量的數據也需要很長時間。

您可以做的主要事情是提高代碼的效率,以便注意對於任何一對數字因素,其中一個因子的數量不會超過數字的平方根。您可以使用這個事實來限制循環,以減少O(n)到O(log n)的算法順序。

long sqrt = Math.sqrt(number); 

for (long i = 2; i < sqrt; i++) { 
    ... 

還有很多其他的事情可以做,但是這個改變會產生最大的影響。

如果在循環過程number變化值(例如在你的第二個上分解循環),你當然如果需要重新計算終值:

for (...) 
    // if number changes 
    sqrt = Math.sqrt(number); 
+1

當'數字'是素數或只有兩個因素時,這會更快。當'number'有很多因素時它會變慢。在原始算法中,每次找到一個因子時,num都會減少,並且每次找到一個因子時,剩下的要除以的數量就會減少。你的方法沒有考慮到這一點。現在,隨着越來越高的原始數值,這些數值中越來越大的比例具有多個因素,並且比例越來越小。這意味着,在一般情況下,這種變化實際上會使表演... – 2015-04-01 07:30:40

+0

...惡化,而不是改善它。當然,在原始數字爲23456789的特定情況下,這是一個改進,只是因爲這個數字恰好是質數。 – 2015-04-01 07:31:26

+0

@david我不確定你想要做什麼。迭代從2到sqrt(num)所需的迭代次數少於從2到num的迭代次數 - 只是沒有得到解決。它*必須*更快。至於* second *循環,尋找因素,我並不是建議循環的內容被改變,只是外部循環被限制到sqrt(num)。再一次,這*必須*比在數字上限更快。正如我所說的,還有更多的事情可以做,但是從O(n)到O(log n)這樣一個簡單的改變對於降壓來說肯定是好的。 – Bohemian 2015-04-01 09:56:39

3

沒有實際的錯誤 - 你只是在做一個非常低效的方法。基本上,你在檢查每個數字之間的1和23456789之間的首要性,在分裂之前。

這樣做是完全沒有意義的。當你從1到23456789工作時,每當你發現一個因素時,你就知道它必須是素數,因爲你已經劃分了所有較小的因子。因此,如果您執行以下所有操作,則此功能仍能正常工作,而且速度更快。

  • 徹底刪除isPrime方法。
  • 取出線if (isPrime(j)) {,並且匹配}
  • 改變環路以便j開始於2,像for(long j = 2 ; j <= num ; j++) {
  • 從迴路的末端刪除if (num == 1) { break; }。它根本沒有任何用處。
+0

你的解決方案似乎不起作用,現在我的代碼不會輸出任何給定數量的小號或大號碼。 – CoderJ 2015-03-30 19:49:17

+0

哦,你需要在2開始'j'而不是1,否則你只會一遍又一遍地分開。我將編輯解決方案。 – 2015-03-30 20:10:09

+0

完美無瑕地工作,非常感謝:) – CoderJ 2015-03-30 20:29:24