2015-03-30 6 views
0

Вот моя программа для вывода простой факторизации заданного числа. Я все еще просто новичок в java, поэтому я знаю, что это не самый эффективный код. Проблема возникает при вводе относительно больших чисел.Как исправить мою основную программу факторизации?

Вход: 11 Выход: 11

Вход: 40 Выход: 2 2 2 5

Вход: 5427 Выход: 3 3 3 3 67

Входной сигнал: 435843 Выход: 3 3 79 613

Input: 23456789 Output: нет (нет, кажется, бесконечный цикл и код должен возвращать 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

ответ

-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' является простым или имеет только два фактора. Это будет медленнее, когда 'number' имеет много факторов. В исходном алгоритме 'num' уменьшается каждый раз, когда найден фактор, и каждый раз, когда обнаруживается фактор, осталось меньше чисел, чтобы разделить их. Ваш метод не учитывает это. Теперь, когда вы получаете более высокие и более высокие значения исходного числа, большая и большая доля этих значений имеет несколько факторов, а меньшая и меньшая пропорция - просто. Это означает, что в общем случае это изменение действительно сделает производительность ... –

+0

... ухудшится, а не улучшится. Конечно, в конкретном случае, когда исходный номер 23456789, это улучшение, просто потому, что это число является простым. –

+0

@ david Я не уверен, в какой момент вы пытаетесь сделать. Итерация от 2 до sqrt (num) занимает меньше итераций, чем итерация от 2 до num - там не обойтись. Он должен быть быстрее. Что касается * second * loop, то найти факторы, я не предполагаю, что содержимое цикла будет изменено, просто чтобы внешний цикл был закрыт до sqrt (num). Опять же, это * должно * быть быстрее, чем укутывание в num. Как я уже сказал, есть много вещей, которые можно сделать, но переход от O (n) к O (log n) с таким простым изменением - это, безусловно, хороший удар для доллара. – Bohemian

3

Нет фактической ошибки - вы просто делаете очень неэффективный способ. В основном, вы проверяете каждое число от 1 до 23456789 за грубость, прежде чем делить.

Нет абсолютно никакого дела в этой проверке. Когда вы работаете с 1 по 23456789, каждый раз, когда вы обнаруживаете фактор, вы знаете, что он должен быть простым, потому что вы уже разделили все более мелкие факторы. Поэтому, если вы выполните все следующие действия, это будет работать корректно и намного быстрее.

  • Извлеките метод isPrime полностью.
  • Удалите строку if (isPrime(j)) { и соответствие }
  • Изменить петлю так, чтобы j начинается на 2, как for(long j = 2 ; j <= num ; j++) {
  • Удалить if (num == 1) { break; } от конца цикла. Это нецелесообразно.
+0

Ваше решение не работает, теперь мой код не выводит ни одного номера для любого заданного числа, малого или большого. – CoderJ

+0

О, вам нужно начать 'j' на 2, а не на 1, иначе вы просто делитесь на 1 снова и снова. Я отредактирую решение. –

+0

Работает безупречно, большое спасибо :) – CoderJ