Java Prime Factorization: время ожидания программы истекло?

Прежде чем меня осудят за несоблюдение правил, я ДЕЙСТВИТЕЛЬНО воспользовался функцией поиска и увидел, что есть несколько тем, посвященных именно этой проблеме. Однако ни один из них не ответил на мой конкретный вопрос.

Я работаю над задачей Эйлера №3, где мне нужно найти наибольший простой делитель числа 600851475143. Мне не нужна помощь в решении задачи. Я использовал метод грубой силы (может быть лучше , я знаю) для ее решения.

Программа возвращается правильно для всех тестов, которые я провел с меньшими числами (7 цифр и меньше). Однако, когда я ввожу 600851475143 в качестве длинного ввода, моя программа никогда не возвращает мне результат. Мой номер просто слишком велик для ввода? Что может быть причиной этого? Первоначально я думал, что это потому, что я использовал теги int вместо long, но их изменение не изменило мой результат.

Я уверен, что это просто, и мне этого не хватает, но мне очень любопытно, что происходит. Заранее спасибо :)

//Euler 3: Largest Prime Factor
import java.io.*;
import java.util.Scanner;
import java.lang.Math;


public class Euler3 
{
    public static void main(String[] args)
    {
        Scanner scn = new Scanner(System.in);

        System.out.println("Enter a number!");
        // Create scanner
        long numberInput=scn.nextLong();
        //Can't have a factor higher than it's square root
        double limit=Math.floor(Math.sqrt(numberInput));
        // System.out.println(limit);

        //Start testing from the highest number possible
        for(long i=(numberInput-1);i>0; i--)
        {
            if(numberInput%i==0) 
                System.out.println(i+" is prime: "+isPrime(i));

        }

    } //End Main


    public static boolean isPrime(long n) 
    {
        //check if n is a multiple of 2
        if (n%2==0) return false;
        //if not, then just check the odds
        for(int i=3;i*i<=n;i+=2)
        {
            if(n%i==0)
                return false;
        }
        return true;
    }
}   

person Community    schedule 21.05.2013    source источник
comment
Я бы пересмотрел, мне не нужна помощь в решении проблемы. Я сделал метод грубой силы (может быть лучше, я знаю) для его решения. - Многие задачи Project Euler (и конкуренции кода) спроектированы так, чтобы их невозможно было решить с помощью реализаций грубой силы с плохими границами. Запустите код с постепенно увеличивающимися значениями (от того, который работает быстро) и отобразите время на графике — как это выглядит?   -  person user2246674    schedule 21.05.2013


Ответы (3)


Чтобы проверить, является число простым или нет, используйте решето Эратосфена, оно будет работать намного быстрее. по сравнению с вашим наивным isPrime методом. Я не буду давать никаких советов по реализации из-за этой фразы: Мне не нужна помощь в решении проблемы.

Кроме того, могут быть и другие подсказки, которые вы пропустили. Рекомендую ознакомиться с постановкой задачи:

Каков самый большой простой множитель

person Luiggi Mendoza    schedule 21.05.2013

Переменная long может легко разместить желаемое значение.

long: тип данных long представляет собой 64-битное целое число в дополнении до двух со знаком. Он имеет минимальное значение -9 223 372 036 854 775 808 и максимальное значение 9 223 372 036 854 775 807 (включительно). Используйте этот тип данных, когда вам нужен диапазон значений, более широкий, чем предоставленный int.

Проблема в том, что ваш алгоритм неэффективен. Как уже упоминалось, используйте решето Эратосфена.

person Steve    schedule 21.05.2013

Проблема не в методе isPrime, а в цикле, который вы используете для его вызова. Вы считаете в обратном порядке от своего числа n с шагом 1, а isPrime вызываете только для делителей n: потребуется n/2 шагов, прежде чем вы доберетесь до первого потенциального делителя n - таким образом, в порядке 10^12 шагов для вашего пример n.

person Arend    schedule 29.05.2013