1

I'm trying to feed each prime number found into a chain of "sieve" objects. The below code achieves what I eventually want to do, but each sieve (Prime number)class is manually implemented (to check subsequent numbers are divisible by the stored prime then they should be discarded, otherwise they should be forwarded to the next sieve in the chain), is there a way I can do this dynamically, that is every-time a new prime number is found I will have to create a sieve object. Any help is much appreciated.

#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 <<" ";


    }
}
Jerry
  • 424
  • 1
  • 4
  • 17
  • I would like to help you somehow, but can't because re-read your question several times and still can't understand for what reason you had wrote this code. Maybe it will be better to provide some example without code, just in text, action by action. – cassandrad Mar 05 '15 at 15:13
  • What about creating 1 Sieve class that obtains the previous one (and perhaps a number to track the prime number you need)? You could track this in a list? – Floris Velleman Mar 05 '15 at 15:26
  • My main task is to generate numbers starting from 2 and feed into a chain of “sieve” objects. Each sieve should store the first number it receives (the prime numbers) and print it out. Subsequent numbers should then be checked for divisibility by that prime. If the subsequent numbers are divisible by the stored prime then they should be discarded, otherwise they should be forwarded to the next sieve in the chain. I need to do something like this in c++: [link](http://www.cs.dartmouth.edu/~cs10/notes/27/Sieve.java) – Jerry Mar 05 '15 at 15:27
  • Why not do it similar to: http://primesieve.org/segmented_sieve.html – Deepfreeze Mar 05 '15 at 16:13

1 Answers1

1

If I understand your question right, you could replace all your Sieve2, Sieve3, ... classes by this:

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_;
};

Then, your calling code would be:

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 <<" ";
  }
}

However, I would rather put the sequencing logic outside of your Sieve classes and into something that can be more easily reasoned about like an outside container.

Martin J.
  • 5,028
  • 4
  • 24
  • 41
  • Thats correct, also I do not want to manually create the PrimeSieve objects, but dynamically create them evreytime a new prime number is found. – Jerry Mar 05 '15 at 15:52
  • I added that part in, again assuming I understand correctly – Martin J. Mar 05 '15 at 16:00