From 42e1246ffcbb2954bbb20cc4a7c51a8611fe8fd6 Mon Sep 17 00:00:00 2001 From: Filip Hlasek Date: Thu, 23 Jul 2020 04:50:38 -0700 Subject: [PATCH] fix, test: Refactor of sieve_of_eratosthenes (#969) * fix, test: Refactor of sieve_of_eratosthenes * Add missing include. * Modernize the vector initialization. * Add @details for the documentation. --- math/sieve_of_eratosthenes.cpp | 56 +++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/math/sieve_of_eratosthenes.cpp b/math/sieve_of_eratosthenes.cpp index e30bc1891..e011b6c00 100644 --- a/math/sieve_of_eratosthenes.cpp +++ b/math/sieve_of_eratosthenes.cpp @@ -1,58 +1,72 @@ /** * @file * @brief Get list of prime numbers using Sieve of Eratosthenes - * Sieve of Eratosthenes is an algorithm to find the primes - * that is between 2 to N (as defined in main). + * @details + * Sieve of Eratosthenes is an algorithm that finds all the primes + * between 2 and N. * - * Time Complexity : \f$O(N \cdot\log N)\f$ + * Time Complexity : \f$O(N \cdot\log \log N)\f$ *
Space Complexity : \f$O(N)\f$ * * @see primes_up_to_billion.cpp prime_numbers.cpp */ -#include // for io operations +#include +#include +#include /** - * This is the function that finds the primes and eliminates - * the multiples. + * This is the function that finds the primes and eliminates the multiples. + * Contains a common optimization to start eliminating multiples of + * a prime p starting from p * p since all of the lower multiples + * have been already eliminated. * @param N number of primes to check - * @param [out] isprime a boolean array of size `N` identifying if `i`^th number is prime or not + * @return is_prime a vector of `N + 1` booleans identifying if `i`^th number is a prime or not */ -void sieve(uint32_t N, bool *isprime) { - isprime[0] = true; - isprime[1] = true; +std::vector sieve(uint32_t N) { + std::vector is_prime(N + 1, true); + is_prime[0] = is_prime[1] = false; for (uint32_t i = 2; i * i <= N; i++) { - if (!isprime[i]) { - for (uint32_t j = (i << 1); j <= N; j = j + i) { - isprime[j] = true; + if (is_prime[i]) { + for (uint32_t j = i * i; j <= N; j += i) { + is_prime[j] = false; } } } + return is_prime; } /** * This function prints out the primes to STDOUT * @param N number of primes to check - * @param [in] isprime a boolean array of size `N` identifying if `i`^th number is prime or not + * @param is_prime a vector of `N + 1` booleans identifying if `i`^th number is a prime or not */ -void print(uint32_t N, const bool *isprime) { +void print(uint32_t N, const std::vector &is_prime) { for (uint32_t i = 2; i <= N; i++) { - if (!isprime[i]) { + if (is_prime[i]) { std::cout << i << ' '; } } std::cout << std::endl; } +/** + * Test implementations + */ +void tests() { + // 0 1 2 3 4 5 6 7 8 9 10 + std::vector ans{false, false, true, true, false, true, false, true, false, false, false}; + assert(sieve(10) == ans); +} + /** * Main function */ int main() { - uint32_t N = 100; - bool *isprime = new bool[N]; - sieve(N, isprime); - print(N, isprime); - delete[] isprime; + tests(); + uint32_t N = 100; + std::vector is_prime = sieve(N); + print(N, is_prime); return 0; }