Find the Number of Primes In A Subarray using C++


In this article we will describe the ways to find the number of primes in a subarray. We have an array of positive numbers arr[] and q queries having two integers that denote our range {l, R} we need to find the number of primes in the given range. So below is an example of the given problem −

Input : arr[] = {1, 2, 3, 4, 5, 6}, q = 1, L = 0, R = 3

Output : 2

In the given range the primes are {2, 3}.

Input : arr[] = {2, 3, 5, 8 ,12, 11}, q = 1, L = 0, R = 5

Output : 4

In the given range the primes are {2, 3, 5, 11}.

Approach to Find the Solution

In this situation, two approaches come to mind −

Brute Force

In this approach, we can take the range and find the number of primes present in that range.

Example

#include <bits/stdc++.h>
using namespace std;
bool isPrime(int N){
    if (N <= 1)
       return false;
    if (N <= 3)
       return true;
    if(N % 2 == 0 || N % 3 == 0)
       return false;
    for (int i = 5; i * i <= N; i = i + 2){ // as even number can't be prime so we increment i by 2.
       if (N % i == 0)
           return false; // if N is divisible by any number then it is not prime.
    }
    return true;
}
int main(){
    int N = 6; // size of array.
    int arr[N] = {1, 2, 3, 4, 5, 6};
    int Q = 1;
    while(Q--){
        int L = 0, R = 3;
        int cnt = 0;
        for(int i = L; i <= R; i++){
           if(isPrime(arr[i]))
               cnt++; // counter variable.
        }
        cout << cnt << "\n";
    }
    return 0;
}

Output

2

However, this approach is not very good as the overall complexity of this approach is O(Q*N*√N), which is not very good.

Efficient Approach

In this approach, we will use Sieve Of Eratosthenes to make a boolean array that tells us whether the element is prime or not, and then go through the given range and find the total number of primes from the bool array.

Example

#include <bits/stdc++.h>
using namespace std;
vector<bool> sieveOfEratosthenes(int *arr, int n, int MAX){
    vector<bool> p(n);
    bool Prime[MAX + 1];
    for(int i = 2; i < MAX; i++)
       Prime[i] = true;
    Prime[1] = false;
    for (int p = 2; p * p <= MAX; p++) {
       // If prime[p] is not changed, then
       // it is a prime
       if (Prime[p] == true) {
           // Update all multiples of p
           for (int i = p * 2; i <= MAX; i += p)
               Prime[i] = false;
       }
    }
    for(int i = 0; i < n; i++){
        if(Prime[arr[i]])
           p[i] = true;
        else
           p[i] = false;
    }
    return p;
}
int main(){
    int n = 6;
    int arr[n] = {1, 2, 3, 4, 5, 6};
    int MAX = -1;
    for(int i = 0; i < n; i++){
        MAX = max(MAX, arr[i]);
    }
    vector<bool> isprime = sieveOfEratosthenes(arr, n, MAX); // boolean array.
    int q = 1;
    while(q--){
        int L = 0, R = 3;
        int cnt = 0; // count
        for(int i = L; i <= R; i++){
            if(isprime[i])
               cnt++;
       }
       cout << cnt << "\n";
   }
   return 0;
}

Output

2

Explanation of the Above Code

This approach is much faster than the Brute Force approach that we applied earlier as now the time complexity is O(Q*N) which is much better than the previous complexity.

In this approach, we precalculate the elements and flag them as prime or not; thus, this reduces our complexity. Above that, we are also using Sieve Of Eratosthenes, which will help us find prime numbers faster. In this method, we flag all the numbers as prime or not prime in O(N*log(log(N))) complexity by flagging numbers using their prime factors.

Conclusion

In this article, we solve a problem to find the Number Of Primes In A Subarray in O(Q*N) using Sieve Of Eratosthenes. We also learned the C++ program for this problem and the complete approach (Normal and efficient) by which we solved this problem. We can write the same program in other languages such as C, java, python, and other languages.

Updated on: 24-Nov-2021

171 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements