Для тех ответов, которые используют метод isPrime(int) : boolean
, существует более быстрый алгоритм, чем ранее реализованный (что-то вроде)
private static boolean isPrime(long n) { //when n >= 2
for (int k = 2; k < n; k++)
if (n % k == 0) return false;
return true;
}
и это так:
private static boolean isPrime(long n) { //when n >= 2
if (n == 2 || n == 3) return true;
if (n % 2 == 0 || n % 3 == 0) return false;
for (int k = 1; k <= (Math.floor(Math.sqrt(n)) + 1) / 6; k++)
if (n % (6 * k + 1) == 0 || n % (6 * k - 1) == 0) return false;
return true;
}
Я сделал этот алгоритм, используя два факта:
- Нам нужно проверить только
n % k == 0
до k <= Math.sqrt(n)
. Это правда, потому что для чего-то более высокого, факторы просто «переворачивают» бывших. рассмотрим случай n = 15
, где 3 * 5
= 5 * 3
и 5
> Math.sqrt(15)
. Нет необходимости в таком совпадении проверки как 15 % 3 == 0
, так и 15 % 5 == 0
, когда мы можем просто проверить одно из этих выражений.
- Все простые числа (кроме
2
и 3
) могут быть выражены в виде (6 * k) + 1
или (6 * k) - 1
, потому что любое положительное целое число может быть выражено в виде (6 * k) + n
, где n = -1, 0, 1, 2, 3, or 4
и k
является целым числом <= 0
, и случаи, когда n = 0, 2, 3, and 4
все приводимы.
Следовательно, n
является простым, если оно не делится на 2
, 3
или на некоторое целое число вида 6k ± 1 <= Math.sqrt(n)
. Отсюда и вышеприведенный алгоритм.
-
Статья в Википедии о тестировании на простоту
-
Редактировать: Думаю, что я мог бы также опубликовать свое полное решение (* я не использовал isPrime()
, и мое решение почти идентично верхнему ответу, но я подумал, что должен ответить на фактический вопрос):
public class Euler3 {
public static void main(String[] args) {
long[] nums = {13195, 600851475143L};
for (num : nums)
System.out.println("Largest prime factor of " + num + ": " + lpf(num));
}
private static lpf(long n) {
long largestPrimeFactor = 1;
long maxPossibleFactor = n / 2;
for (long i = 2; i <= maxPossibleFactor; i++)
if (n % i == 0) {
n /= i;
largestPrimeFactor = i;
i--;
}
return largestPrimeFactor;
}
}