Last active
December 19, 2015 03:09
-
-
Save cire3791/5888213 to your computer and use it in GitHub Desktop.
Sieve of Eratosthenes implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iomanip> | |
#include <iostream> | |
#include <vector> | |
#include "Sieve.h" | |
template <typename T> | |
void print( std::ostream& os, const T& t ) | |
{ | |
const unsigned perRow = 10 ; | |
const unsigned rowSize = 80 ; | |
for ( unsigned i=0; i<t.size(); ++i ) | |
{ | |
if ( i && !(i % perRow) ) | |
os << '\n' ; | |
os << std::setw(rowSize/perRow) << t[i] ; | |
} | |
os << '\n' ; | |
} | |
int main() | |
{ | |
auto primes = generatePrimes(1009) ; | |
print(std::cout, primes) ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vector> | |
#include "Sieve.h" | |
namespace | |
{ | |
typedef std::vector<bool> sieve_type ; | |
const Sieve::size_type beginValue = 3 ; | |
Sieve::size_type toIndex( Sieve::value_type value ) | |
{ | |
return (value - beginValue) / 2 ; | |
} | |
Sieve::value_type toValue( Sieve::size_type index ) | |
{ | |
return (index * 2) + beginValue ; | |
} | |
} | |
struct Sieve::Impl | |
{ | |
sieve_type _sieve ; | |
sieve_type::size_type _curIdx ; | |
Impl(Sieve::size_type) ; | |
void unmarkMultiples() ; | |
bool next(Sieve::value_type& prime) ; | |
}; | |
Sieve::Impl::Impl(Sieve::size_type limit) : _sieve((limit-1)/2, true), _curIdx(0) | |
{ | |
} | |
void Sieve::Impl::unmarkMultiples() | |
{ | |
const Sieve::size_type step = toValue(_curIdx) ; | |
for ( Sieve::size_type i = toIndex(step*step) ; i < _sieve.size(); i += step ) | |
_sieve[i] = false ; | |
} | |
bool Sieve::Impl::next(Sieve::value_type& prime) | |
{ | |
if ( _curIdx >= _sieve.size() ) | |
return false ; | |
unmarkMultiples() ; | |
prime = toValue(_curIdx++) ; | |
while ( _curIdx < _sieve.size() && !_sieve[_curIdx] ) | |
++_curIdx ; | |
return true ; | |
} | |
Sieve::Sieve(size_type size) : _impl(new Impl(size)) | |
{ | |
} | |
bool Sieve::operator()(value_type& val) | |
{ | |
return _impl->next(val) ; | |
} | |
std::vector<Sieve::value_type> generatePrimes(Sieve::size_type limit) | |
{ | |
std::vector<Sieve::value_type> primes(1,2) ; | |
Sieve sieve(limit) ; | |
Sieve::value_type val ; | |
while ( sieve(val) ) | |
primes.push_back(val) ; | |
return std::move(primes) ; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef EMS_SIEVE_INCLUDED_ | |
#define EMS_SIEVE_INCLUDED_ | |
#include <memory> | |
class Sieve | |
{ | |
public: | |
typedef unsigned value_type ; | |
typedef unsigned size_type ; | |
Sieve( size_type limit ) ; | |
bool operator()( value_type& ) ; | |
private: | |
struct Impl ; | |
std::unique_ptr<Impl> _impl ; | |
}; | |
std::vector<Sieve::value_type> generatePrimes(Sieve::size_type limit) ; | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment