在这段代码中,我想解决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;
}
}
答案 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;
}