2009-11-01 3 views
1
class eulerThree { 

    public static void main(String[] args) { 

     double x = 600851475143d; 

     for (double z = 2; z*z <= x; z++) { 

      if (x%z == 0) { 

       System.out.println(z + "PRIME FACTOR"); 

      } 

     } 

    } 

} 

и выход:Проект Эйлера # 3 Java Решение проблемы

71.0 
839.0 
1471.0 
6857.0 
59569.0 
104441.0 
486847.0 

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

ответ

4

Во-первых, вы должны использовать точное арифметическое средство. Другие предложили использовать BigInteger. Вы можете сделать это. Для меня это немного напоминает обман (это будет более важно для более поздних проблем, связанных с гораздо большими целыми числами), поэтому более интересным способом (imho) является запись необходимых операций произвольной точности самостоятельно.

Во-вторых, 600851475143 является достаточно маленьким, чтобы сделать точный с long, который будет намного быстрее.

В-третьих, ваша петля неправильно проверяет основные факторы. Вы просто проверяете нечетные числа. Это пустое (неполное) решение:

long num = 600851475143L; 
List<Long> factors = new ArrayList<Long>(); // or use a Set 
if (num & 1 == 0) { 
    factors.add(2L); 
} 
for (long i=3; i*i<=num; i+=2) { 
    // first check i is prime 
    // if i is prime check if it is a factor of num 
} 

Проверка того, что что-то простое имеет разные уровни реализации. Самые наивные:

public boolean isPrime(long num) { 
    for (long i=2; i<=num; i++) { 
    if (num % i == 0) { 
     return false; 
    } 
    } 
    return true; 
} 

Конечно, это делает все виды ненужной проверки.Как вы уже определили, что вам нужно только проверить номера до sqrt(n) и вы можете устранить даже номера (кроме 2):

public boolean isPrime(long num) { 
    if (num & 1 == 0) { 
    return false; // checks divisibility by 2 
    } 
    for (long i=3; i*i<=num; i+=2) { 
    if (num % i == 0) { 
     return false; 
    } 
    } 
    return true; 
} 

Но вы можете сделать лучше, чем это, как хорошо. Другая оптимизация заключается в том, что вам нужно всего лишь проверить номер на простых номеров в этом диапазоне. Основными коэффициентами 63 являются 3 и 7. Если число не делится на 3 или 7, то по определению оно не будет делиться на 63.

Так что вы хотите создать, вероятно, Set<Long> или простых чисел, пока квадрат не будет равен или больше вашего целевого номера. Затем просто проверьте эту серию чисел для делимости на цель.

2

double по своей сути является неточным для больших значений и должен никогда не использовать для операций такого типа. Правильный класс для использования - BigInteger, который позволяет точно представить сколь угодно большие интегральные значения. См. this wikipedia article для описания того, какие типы данных с плавающей точкой являются и нет.

1

Во-первых, используйте BigInteger или длинный, а не двойной. Двойной не является точным, и по мере того, как вы доберетесь до более поздних проблем, это будет неверно.

Во-вторых, то, что вы печатаете, это факторы, а не простые факторы.

Это будет работать в вашем случае:

for (double z = 2; z <= x; z++) { 
     if (x%z == 0) { 
        while(x%z == 0) 
         x = x/z 
       System.out.println(z + "PRIME FACTOR"); 
     } 
} 

Кроме того, проект Эйлера дает вам образец ввода и вывода. Используйте это, так как ваш код не выводит значения, соответствующие примеру, который они приводят в проблеме.

1

Две вещи:

  1. Не используйте double, тем больше число, тем меньше точность имеет. Вместо этого вы можете использовать BigInteger для хранения произвольно больших целых чисел, или в этом случае достаточно простого long.

  2. Вам необходимо разделить основной коэффициент после того, как найдете его, иначе вы найдете все факторы, а не только простые факторы. Что-то вроде этого:

    if (x % z == 0) { 
        System.out.println(z + "PRIME FACTOR"); 
        x /= z; 
        z -= 1; // Might be present multiple times, try it again 
    } 
    
0
public class Prime { 
    public static void main(String[] args) { 
     double out = 0; 
     double m = 600851475143d; 
     for (double n = 3; n < m; n += 2) { 
      while (m % n == 0) { 
       out = n; 
       m = m/n; 
      } 
     } 
     System.out.println("" + ((m == 1)?out:m)); 
    } 
} 

Посмотрите программу. И вы поймете алгоритм. Это очень легко и очень быстро. И верните правильный ответ 6857.

0
  import java.util.Scanner; 

      class Primefactor 
        { 
          public static void main(String args[]) 
           { 
         Scanner get=new Scanner(System.in); 
         System.out.println("Enter a number"); 
         long number=get.nextLong(); 
         int count=0; 
         long input=number; 
          for(long i=number;i>=1;number--) 
           { 
        for(long j=number;j>=1;j--) 
        { 
         if(i%j==0) 
         { 
          count++; 
         } 
         if(count==2) 
         { 
          if(input%j==0) 
           { 
           System.out.println(j); 
           } 
          } 
        } 
        } 
      } 
      } 

Это должно увидеть самый большой премьер-фактор любого числа в пределах ограничения типа данных.

0
public static void largestPrimeNo(long lim) 
{ 
long newNum = lim; 
long largestFact = 0; 

int counter = 2; 
while(counter * counter <= newNum) 
{ 
if(newNum % counter == 0) 
{ 
    newNum = newNum/counter; 
    largestFact = counter; 
}else{ 
counter++; 
} 
} 
if(newNum > largestFact) 
{ 
largestFact=newNum; 
} 
System.out.println(largestFact); 
} 
} 

, как премьер не является работа по принципу, что Any integer greater than 1 is either a prime number, or can be written as a unique product of prime numbers .so мы можем легко использовать выше program.In эту программу мы разделим давно нет, и найти его главным фактором

0
package findlaragestprimefactor; 

public class FindLaragestPrimeFactor{ 

    boolean isPrime(long number) { 
     for (long divider = 2; divider <= number/2; divider++) { 
      if (number % divider == 0) { 
       return false; 
      } 

     } 
     return true; 
    } 

    void calculateLargestPrimeFactor() { 
     long largestPrimeFactor = 0; 
     long x = 600851475143L; 
     for(long factor = 3 ; factor <= x/2 ; factor = factor + 2){ 
      if(x%factor==0 & factor>largestPrimeFactor & isPrime(factor)){ 
       largestPrimeFactor = factor; 
      } 
     } 
     System.out.println(largestPrimeFactor); 
    } 







    public static void main(String[] args) { 

     MyProject m = new MyProject(); 
     m.calculateLargestPrimeFactor(); 
    } 
}