📜  计算最多为N的质数,可以表示为两个质数之和

📅  最后修改于: 2021-04-17 17:19:07             🧑  作者: Mango

给定一个正整数N ,任务是查找小于或等于N的质数计数,该计数可以表示为两个质数之和。

例子:

天真的方法:解决给定问题的最简单方法是考虑范围[1,N]内的所有可能对(i,j),如果ij是质数并且(i + j)在范围[1] ,N],然后增加素数的计数。检查所有可能的对之后,打印获得的总计数值。
时间复杂度: O(N 3 )
辅助空间: O(1)

高效的方法:还可以基于以下观察来优化上述方法:

  • 2外,所有素数均为奇数
  • 无法将质数(奇数)表示为两个奇数质数之和,因此两个质数之一应为2
  • 因此,要使质数X为两个质数之和, X – 2也必须是质数。

请按照以下步骤解决问题:

  • 初始化一个数组,假设其大小为10 5的prime [] ,并使用Eratosthenes筛子填充所有质数直到10 5。
  • 初始化大小为(N +1)的辅助数组dp [] ,其中dp [i]是小于或等于i的质数的计数,可以表示为2个质数的总和。
  • 使用变量i遍历[2,N]范围,并执行以下步骤:
    • 将dp [i – 1]的值更新为dp [i – 1]dp [i]的总和。
    • 检查prime [i]prime [i – 2]是否为true ,然后将dp [i]的值增加1
  • 完成上述步骤后,打印dp [N]的值作为结果计数。

下面是上述方法的实现:

C++
// C++ program for the above approach
  
#include 
using namespace std;
  
// Function to store all prime numbers
// up to N using Sieve of Eratosthenes
void SieveOfEratosthenes(
    int n, bool prime[])
{
    // Set 0 and 1 as non-prime
    prime[0] = 0;
    prime[1] = 0;
  
    for (int p = 2; p * p <= n; p++) {
  
        // If p is prime
        if (prime[p] == true) {
  
            // Set all multiples
            // of p as non-prime
            for (int i = p * p;
                 i <= n; i += p) {
                prime[i] = false;
            }
        }
    }
}
  
// Function to count prime numbers
// up to N that can be represented
// as the sum of two prime numbers
void countPrime(int n)
{
    // Stores all the prime numbers
    bool prime[n + 1];
    memset(prime, true, sizeof(prime));
  
    // Update the prime array
    SieveOfEratosthenes(n, prime);
  
    // Create a dp array of size n + 1
    int dp[n + 1];
  
    memset(dp, 0, sizeof(dp));
  
    // Update dp[1] = 0
    dp[1] = 0;
  
    // Iterate over the range [2, N]
    for (int i = 2; i <= n; i++) {
  
        // Add the previous count value
        dp[i] += dp[i - 1];
  
        // Increment dp[i] by 1 if i
        // and (i - 2) are both prime
        if (prime[i] == 1
            && prime[i - 2] == 1) {
            dp[i]++;
        }
    }
  
    // Print the result
    cout << dp[n];
}
  
// Driver Code
int main()
{
    int N = 6;
    countPrime(N);
  
    return 0;
}


输出:
1

时间复杂度: O(N * log(log(N)))
辅助空间: O(N)