如何减少函数运行时间

时间:2015-01-06 23:48:55

标签: java performance

在这段代码中,我想解决Project Euler Problem#3。目标是找到最大的素数。我的代码运行正常,但运行时出现问题。如何减少运行时间?任何人都可以建议任何提示吗?

public class Euler3 {

    //https://www.hackerrank.com/contests/projecteuler/challenges/euler003
    public static void main(String[] args) {

        long[] inputs = readInputs();

        for (int i = 0; i < inputs.length; i++) {

            System.out.println(findBiggestPrime(inputs[i]));
        }

    }

    public static boolean isPrime(long num) {

        if (num == 2)
            return true;

        for (long i = 3; i * i <= num; i += 2) {

            if (num % i == 0)
                return false;

        }

        return true;
    }

    private static long[] readInputs() {

        Scanner scanner = new Scanner(System.in);
        int inputQuantities = scanner.nextInt();

        long[] inputs = new long[inputQuantities];

        for (int i = 0; i < inputQuantities; i++) {

            inputs[i] = scanner.nextLong();
        }
        return inputs;
    }

    private static long findBiggestPrime(long number) {

        long biggestPrime = 0;

        if (number % 2 == 0) {

            number = number / 2;
            biggestPrime = 2;
        }

        if (number == 2) 
            return 2;



        for (int i = 3; i <= number; i += 2) {

            if (number % i != 0)  
            continue;

            if(!isPrime(i)) 
                continue;;

                biggestPrime = i;
                number = number / biggestPrime;

        }


        return biggestPrime;
    }


}

2 个答案:

答案 0 :(得分:4)

if(!isPrime(i)) 
     continue;

会降低你的算法速度,不应该在那里。

您在算法中遇到的任何因素都应自动为素数。例如,您不应该遇到因子15,因为您应该已经遇到过3和5并且除以它们。

为了完成这项工作,你不应该只做number = number / biggestPrime;。当你遇到一个因素时,你应该继续除以它,直到它不再进入数字。这样你就可以清除权力。

答案 1 :(得分:0)

isPrime()非常低效。这是一个跟踪HashSet中已经确认的倍数的版本。我不知道你正在使用的#的数量级。这似乎在我的机器上在~100K范围内有效率。

private static final Set<Long> multiples = new HashSet<>();

private static boolean isPrime(long l) {
    if(l%2==0 && l>2)
        return false;
    if(multiples.contains(l))
        return false;
    double r = Math.sqrt(l);
    for(long i=3;i<=r;++i) {
        for (long j = i * 2; j <= l; j += i) {
            multiples.add(j);
            if (j == l) {
                return false;
            }
        }
    }
    return true;
}