Вам не нужно ехать через весь список. Когда вы найдете один основной фактор, вы факторизуете свой номер и продолжаете работать с тем, что осталось.
Например, возьмите пример: 600 851 475 143. Вы можете быстро найти свой первый основной коэффициент равным 71. Если вы разделите 600 851 475 143 на 71, вы получите 8 462 696 833. Оба эти числа разделяют одни и те же основные факторы, кроме 71. Теперь вы можете искать наибольший коэффициент исходного числа, но с пространством поиска уменьшено на 2 порядка.
Также обратите внимание, что ваш код не будет работать, если само число является простым. Чтобы исправить это, инициализируйте свое максимальное число как
int largest_prime_factor = 1;
, и если он все еще 1 в конце, верните номер сам.(Вы можете инициализировать number
, но вы скоро увидите, почему я выбрал 1)
Так начните путем обработки 2 как частный случай:
long long remain = number;
while (remain % 2 == 0) {
remain /= 2;
largest_prime_factor = 2;
}
А затем сделать это так же внутри цикла. Поскольку для простых чисел нам нужно только проверить свой квадратный корень, мы ограничим наш цикл двумя случаями, в зависимости от того, считаем ли мы, что число может быть простым.
- Тем не менее простое: проверить до SQRT (число)
- больше не простое: испытание, пока максимальный коэффициент не превышает то, что остается.
В конце концов, ваш измененный код может выглядеть следующим образом:
#include <stdio.h>
int main()
{
long long int number=600851475143;
long long largest_prime_factor = 1,i,j,k;
long long remain = number;
while (remain % 2 == 0) {
remain /= 2;
largest_prime_factor = 2;
/* Uncomment to see the factors
printf("2 ");*/
}
for (i=3; (largest_prime_factor == 1 && i*i <= number) ||
(largest_prime_factor > 1&& i <= remain); i+=2){
k=0;
j=3;
for (j=3; j*j<=i;j+=2){
if (i%j==0){
k++;
break;
}
}
if (k==0 && remain%i==0) {
largest_prime_factor=i;
while (remain % i == 0) {
/* Uncomment to see the factors
printf("%d ", i); */
remain /= i;
}
}
}
printf("The largest prime factor of %Ld is: %Ld",
number, largest_prime_factor);
return 0;
}
заметить также, что другие переменные также должны быть типа (длинный длинный).
Узкое место будет проверять, является ли каждое число простым, и весь процесс будет по-прежнему медленным, если сами основные факторы являются большими. Но вы можете получить гораздо более быстрый средний случай. Для вашего примера этот алгоритм получает коэффициенты 71, 839, 1471 и 6857 менее чем за секунду.
Что вы пробовали до сих пор, чтобы повысить производительность? Как вы компилируете свой код? – Angelos
Этот вопрос прекрасен и по теме, но учтите, что когда у вас есть вопросы о том, как улучшить рабочий код, http://codereview.stackexchange.com/ может дать вам более подробные ответы. – Lundin
Если ваш код работает и вы хотите его оптимизировать, этот пост должен быть включен в обзор кода. Сначала сказал Лундин. – byxor