/* HW #4 - Solution 2 */ /* Eratosthenes' Sieve, Data driven model, optimized */ /* The idea is to maintain a pointer to the last filter. */ /* In this solution such pointer if defined as a member */ /* of Counter and it it forwarded ahead in the chain of filters */ /* via the method in, which also sets its new value. */ /* Note that, in order to have its value set, the pointer */ /* to the last element is passed by reference in the method "in" */ #include class Item { protected: Item* destination; public: ~Item(){ delete destination; } void set_destination(Item* dst){ destination = dst; } virtual void in(int n, Item* &lf){}; }; class Filter: public Item { int factor; public: Filter(int f){ factor = f; destination = NULL; } void in(int n, Item* &lf) { if (n%factor == 0) return; if (n < (factor*factor)) { Filter* temp = new Filter(n); lf -> set_destination(temp); lf = temp; cout << "The next prime number is " << n << " (detected by filter "<< factor << ")\n"; } else if (destination != NULL) destination -> in(n,lf); else { // this case should never occur (cfr. the Prime number Theorem) lf = destination = new Filter(n); cout << "The next prime number is " << n << '\n'; } } }; class Counter: public Item { Item* last_filter; int value; int max; public: Counter(int m){ max = m; } void start(){ if (max < 2) return; last_filter = destination = new Filter(2); cout << "The first prime number is " << 2 << '\n'; value = 3; while (value <= max) destination->in(value++, last_filter); } }; class EratostenesSieve{ int max; Counter* gen; public: EratostenesSieve(int m){ max = m; } void start(){ gen = new Counter(max); gen->start(); } ~EratostenesSieve(){ delete gen; } }; void main() { int max; cout << "Please input the max number to be generated" << '\n'; cin >> max; EratostenesSieve es(max); es.start(); cout << "End\n"; }