Как уже говорилось, ошибок было две:
- вы использовали
int
, который недостаточно велик, чтобы вместить эту сумму .. вы должны были использовать long
- вы использовали
<
вместо этого <=
, и это был неправильный предохранитель для цикла
Кроме того, что вы делаете, это действительно неэффективно, не вдаваясь слишком глубоко в этот класс алгоритмов (как Миллер-Рабин тест) Я бы посоветовал вам взглянуть на Сито Эратосфена .. действительно старый подход, который учит, как решать сложные проблемы простым способомулучшите элегантность и эффективность с помощью компромисса памяти.
Это действительно умно: он отслеживает значение boolean
для каждого простого числа до ваших 2 миллионов, которое утверждает, является ли это число простым или нет.Затем, начиная с первого простого числа, он исключает все последовательные числа, полученные путем умножения простого числа, которое он анализирует, на другое число.Конечно, больше идет и меньше цифр, которые он должен будет проверить (так как он уже исключил их)
Код довольно прост (просто написал его на лету, не проверил):
boolean[] numbers = new boolean[2000000];
long sum = 0;
for (int i = 0; i < numbers.length; ++i)
numbers[i] = true;
for (int i = 2; i < numbers.length; ++i)
if (!numbers[i])
continue;
else {
int j = i + i;
while (j < 2000000) {
numbers[j] = false;
j += i;
}
}
for (int i = 2; i < 2000000; ++i)
sum += numbers[i] ? i : 0;
System.out.println(sum);
Конечно, этот подход все еще не подходит для больших чисел (потому что он все равно должен найти все предыдущие простые числа и из-за памяти), но это хороший пример для начинающих задуматься о проблемах ..