|
1 | 1 | /**
|
2 | 2 | * @file
|
3 | 3 | * @brief Get list of prime numbers using Sieve of Eratosthenes
|
4 |
| - * Sieve of Eratosthenes is an algorithm to find the primes |
5 |
| - * that is between 2 to N (as defined in main). |
| 4 | + * @details |
| 5 | + * Sieve of Eratosthenes is an algorithm that finds all the primes |
| 6 | + * between 2 and N. |
6 | 7 | *
|
7 |
| - * Time Complexity : \f$O(N \cdot\log N)\f$ |
| 8 | + * Time Complexity : \f$O(N \cdot\log \log N)\f$ |
8 | 9 | * <br/>Space Complexity : \f$O(N)\f$
|
9 | 10 | *
|
10 | 11 | * @see primes_up_to_billion.cpp prime_numbers.cpp
|
11 | 12 | */
|
12 | 13 |
|
13 |
| -#include <iostream> // for io operations |
| 14 | +#include <cassert> |
| 15 | +#include <iostream> |
| 16 | +#include <vector> |
14 | 17 |
|
15 | 18 | /**
|
16 |
| - * This is the function that finds the primes and eliminates |
17 |
| - * the multiples. |
| 19 | + * This is the function that finds the primes and eliminates the multiples. |
| 20 | + * Contains a common optimization to start eliminating multiples of |
| 21 | + * a prime p starting from p * p since all of the lower multiples |
| 22 | + * have been already eliminated. |
18 | 23 | * @param N number of primes to check
|
19 |
| - * @param [out] isprime a boolean array of size `N` identifying if `i`^th number is prime or not |
| 24 | + * @return is_prime a vector of `N + 1` booleans identifying if `i`^th number is a prime or not |
20 | 25 | */
|
21 |
| -void sieve(uint32_t N, bool *isprime) { |
22 |
| - isprime[0] = true; |
23 |
| - isprime[1] = true; |
| 26 | +std::vector<bool> sieve(uint32_t N) { |
| 27 | + std::vector<bool> is_prime(N + 1, true); |
| 28 | + is_prime[0] = is_prime[1] = false; |
24 | 29 | for (uint32_t i = 2; i * i <= N; i++) {
|
25 |
| - if (!isprime[i]) { |
26 |
| - for (uint32_t j = (i << 1); j <= N; j = j + i) { |
27 |
| - isprime[j] = true; |
| 30 | + if (is_prime[i]) { |
| 31 | + for (uint32_t j = i * i; j <= N; j += i) { |
| 32 | + is_prime[j] = false; |
28 | 33 | }
|
29 | 34 | }
|
30 | 35 | }
|
| 36 | + return is_prime; |
31 | 37 | }
|
32 | 38 |
|
33 | 39 | /**
|
34 | 40 | * This function prints out the primes to STDOUT
|
35 | 41 | * @param N number of primes to check
|
36 |
| - * @param [in] isprime a boolean array of size `N` identifying if `i`^th number is prime or not |
| 42 | + * @param is_prime a vector of `N + 1` booleans identifying if `i`^th number is a prime or not |
37 | 43 | */
|
38 |
| -void print(uint32_t N, const bool *isprime) { |
| 44 | +void print(uint32_t N, const std::vector<bool> &is_prime) { |
39 | 45 | for (uint32_t i = 2; i <= N; i++) {
|
40 |
| - if (!isprime[i]) { |
| 46 | + if (is_prime[i]) { |
41 | 47 | std::cout << i << ' ';
|
42 | 48 | }
|
43 | 49 | }
|
44 | 50 | std::cout << std::endl;
|
45 | 51 | }
|
46 | 52 |
|
| 53 | +/** |
| 54 | + * Test implementations |
| 55 | + */ |
| 56 | +void tests() { |
| 57 | + // 0 1 2 3 4 5 6 7 8 9 10 |
| 58 | + std::vector<bool> ans{false, false, true, true, false, true, false, true, false, false, false}; |
| 59 | + assert(sieve(10) == ans); |
| 60 | +} |
| 61 | + |
47 | 62 | /**
|
48 | 63 | * Main function
|
49 | 64 | */
|
50 | 65 | int main() {
|
51 |
| - uint32_t N = 100; |
52 |
| - bool *isprime = new bool[N]; |
53 |
| - sieve(N, isprime); |
54 |
| - print(N, isprime); |
55 |
| - delete[] isprime; |
| 66 | + tests(); |
56 | 67 |
|
| 68 | + uint32_t N = 100; |
| 69 | + std::vector<bool> is_prime = sieve(N); |
| 70 | + print(N, is_prime); |
57 | 71 | return 0;
|
58 | 72 | }
|
0 commit comments