Цепочка сит для генерации простых чисел C++
Я пытаюсь скормить каждое найденное простое число в цепочку "ситовых" объектов. Приведенный ниже код выполняет то, что я в конечном итоге хочу сделать, но каждый класс сит (простое число) реализуется вручную (чтобы проверить, что последующие числа делятся на сохраненное простое число, затем они должны быть отброшены, в противном случае они должны быть перенаправлены на следующее сито в цепочка), есть ли способ, которым я могу сделать это динамически, то есть каждый раз, когда будет найдено новое простое число, мне нужно будет создать объект-сито. Буду признателен за любую оказанную помощь.
#include <iostream>
#include <stdio.h>
using namespace std;
class Sieve
{
public:
virtual int NextNumber () = 0;
};
class SourceSieve: public Sieve
{
public:
SourceSieve () : _i (2) {}
int NextNumber ();
private:
int _i;
};
class Sieve2: public Sieve
{
public:
Sieve2 (Sieve & src) : _src (src) { }
int NextNumber ();
private:
Sieve & _src;
};
class Sieve3: public Sieve
{
public:
Sieve3 (Sieve & src) : _src (src) {}
int NextNumber ();
private:
Sieve & _src;
};
class Sieve5: public Sieve
{
public:
Sieve5 (Sieve & src) : _src (src) {}
int NextNumber ();
private:
Sieve & _src;
};
class Sieve7: public Sieve
{
public:
Sieve7 (Sieve & src) : _src (src) {}
int NextNumber ();
private:
Sieve & _src;
};
//Here's the implementation of NextNumber for SourceSieve and Sieve2:
int SourceSieve::NextNumber ()
{
if (_i > 100)
return -1; // end
return _i++;
}
int Sieve2::NextNumber ()
{
int i;
do
{
i = _src.NextNumber ();
} while (i % 2 == 0 && i != 2 && i != -1);
return i;
}
int Sieve3::NextNumber ()
{
int i;
do
{
i = _src.NextNumber ();
} while (i % 3 == 0 && i != 3 && i != -1);
return i;
}
int Sieve5::NextNumber ()
{
int i;
do
{
i = _src.NextNumber ();
} while (i % 5 == 0 && i != 5 && i != -1);
return i;
}
int Sieve7::NextNumber ()
{
int i;
do
{
i = _src.NextNumber ();
} while (i % 7 == 0 && i != 7 && i != -1);
return i;
}
int main ()
{
SourceSieve src;
Sieve2 s2(src);
Sieve3 s3 (s2);
Sieve5 s5 (s3);
Sieve7 s7 (s5);
int i = 1;
for (;;)
{
i = s7.NextNumber();
if (i == -1)
break;
std::cout << i <<" ";
}
}
1 ответ
Если я правильно понимаю ваш вопрос, вы можете заменить все ваши Sieve2
, Sieve3
... занятия по этому:
class PrimeSieve : public Sieve
{
public:
PrimeSieve(Sieve& src, int prime)
: Sieve()
, src_(src)
, prime_(prime) {
}
override int NextNumber () {
int i;
do
{
i = _src.NextNumber ();
} while (i % 2 == 0 && i != 2 && i != -1);
return i;
}
private:
Sieve & src_;
int prime_;
};
Тогда ваш код вызова будет:
int main ()
{
SourceSieve src;
vector<PrimeSieve> sieves;
sieves.emplace_back(src, 2);
int i = 1;
for (;;)
{
auto& currentLastSieve = sieves.back();
i = currentLastSieve.NextNumber();
if (i == -1)
break;
sieves.emplace_back(currentLastSieve. i);
std::cout << i <<" ";
}
}
Тем не менее, я бы предпочел поместить логику секвенирования вне ваших классов Sieve и в нечто, о чем можно легче рассуждать, например, во внешний контейнер.