Я хочу рассчитать количество различных простых множителей каждого целого числа до n. Например, 12 = 2 * 2 * 3, поэтому у него есть 2 разных простых множителя, 2 и 3. Я хочу сохранить каждое из этих значений в массиве result[] размера n+1, в котором result[i] содержит количество различных простых множителей целого числа i.
В своем решении я должен использовать следующий внешний метод:
List<Integer> getPrimes(int n) {
// create array to determine which numbers are prime
boolean isPrime[] = new boolean[n+1];
for(int i=2; i<=n; i++)
isPrime[i] = true; // assume all are prime, we'll filter below
for(int i=3; i*i<=n; i+=2) {
if (isPrime[i]) { // i is prime, so...
for(int j=i*i; j<=n; j+=i) // remove all its multiples
isPrime[j] = false; // by updating array
}
}
// create list with only the prime numbers
List<Integer> primes = new LinkedList<>();
primes.add(2);
for(int i=3; i<=n; i+=2)
if (isPrime[i])
primes.add(i);
return primes;
}
который использует решето Эратосфена для возврата списка всех простых чисел до n. Это было мое решение:
int[] getNumPrimeFactors(int n) {
int[] result = new int[n + 1];
int counter; // counts the number of different prime factors
boolean isPrime = true;
List<Integer> primeList = getPrimes(n);
for (int i = 2; i < result.length; i++) {
counter = 0;
// checks if i is prime
if (i % 2 == 0) {
isPrime = false;
} else {
for (int j = 3; j * j <= i; j += 2) {
if (i % j == 0)
isPrime = false;
}
}
// if i isnt prime, counts how many different prime factors it has
if (!isPrime) {
for (int prime : primeList) {
if (i % prime == 0)
counter++;
}
result[i] = counter;
} else {
result[i] = 1;
}
}
return result;
}
Этот алгоритм дает правильные результаты, однако я хочу проверить n ‹ = 5_000_000, и он недостаточно эффективен. Можно ли как-то улучшить код для очень больших экземпляров n? Вот несколько примеров результатов теста:
Большое спасибо за Вашу помощь :)