Вот простое сито Эратосфена. Он не требует предварительного выделения больших логических массивов, но он все еще >> O (n) во времени и пространстве. Пока у вас достаточно памяти, она должна быть заметно быстрее, чем ваш нынешний наивный метод.
#include <iostream>
#include <map>
using namespace std;
template<typename T = int, typename M = map<T, T> >
class prime_iterator {
public:
prime_iterator() : current(2), skips() { skips[4] = 2; }
T operator*() { return current; }
prime_iterator &operator++() {
typename M::iterator i;
while ((i = skips.find(++current)) != skips.end()) {
T skip = i->second, next = current + skip;
skips.erase(i);
for (typename M::iterator j = skips.find(next);
j != skips.end(); j = skips.find(next += skip)) {}
skips[next] = skip;
}
skips[current * current] = current;
return *this;
}
private:
T current;
M skips;
};
int main() {
prime_iterator<int> primes;
for (; *primes < 1000; ++primes)
cout << *primes << endl;
return 0;
}
Если это все еще слишком медленно для вас, вы можете использовать Сито Аткина , оптимизированное Сито Эратосфена.
На самом деле, они относительно эффективны только в том случае, если диапазон простых чисел начинается с малого. Если нижняя граница уже достаточно велика, а верхняя граница не намного больше нижней, то методы просеивания - это расточительная работа, и вам лучше выполнить тест на первичность .