Цепочка сит для генерации простых чисел 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 и в нечто, о чем можно легче рассуждать, например, во внешний контейнер.

Другие вопросы по тегам