21xrx.com
2024-06-03 00:36:44 Monday
登录
文章检索 我的文章 写文章
C++ 实现统计素数个数的方法
2023-07-14 14:21:33 深夜i     --     --
C++ 统计素数 实现 方法 个数

随着计算机技术和算法的发展,计算素数个数的方法也不断得到改进。其中,C++ 作为一门高效的编程语言,可以很好地实现求解素数个数的功能。本文将介绍 C++ 中几种常见的统计素数个数的方法。

1. 埃拉托斯特尼筛法(Sieve of Eratosthenes)

埃拉托斯特尼筛法是一种简单而高效的算法,它的思路是:从小到大枚举每个数,把它的倍数全部标记为合数,直到最后只剩下素数。具体实现可以用一个布尔数组来表示每个数是否被筛掉,最后统计未被筛掉的素数个数即可。

以下是使用埃拉托斯特尼筛法实现统计素数个数的示例代码:

 C++

int countPrimes(int n) {

  vector<bool> isPrime(n, true); // 初始化所有数为素数

  for (int i = 2; i * i < n; i++) {

    if (!isPrime[i]) continue; // 已经被筛掉了,跳过

    for (int j = i * i; j < n; j += i) {

      isPrime[j] = false; // 标记为合数

    }

  }

  int count = 0;

  for (int i = 2; i < n; i++) {

    if (isPrime[i]) count++; // 统计未被筛掉的素数个数

  }

  return count;

}

2. 线性筛法(Linear Sieve)

线性筛法是对埃拉托斯特尼筛法的优化,它的核心思想是每个合数只被它的最小质因子筛掉一次。具体实现中,从小到大枚举每个数时,除去它的最小质因子后所得到的数为合数,但是由于它已经被它的最小质因子筛掉过了,所以不需要再重复标记。

以下是使用线性筛法实现统计素数个数的示例代码:

 C++

int countPrimes(int n) {

  vector<int> primes; // 存储所有素数

  vector<int> isPrime(n, true); // 初始化所有数为素数

  for (int i = 2; i < n; i++) {

    if (isPrime[i]) {

      primes.push_back(i); // 添加素数到列表中

    }

    for (int j = 0; j < primes.size() && i * primes[j] < n; j++) {

      isPrime[i * primes[j]] = false; // 标记合数

      if (i % primes[j] == 0) break; // 跳出循环,保证每个合数只被它的最小质因子筛掉一次

    }

  }

  return primes.size();

}

3. 埃式筛法(Sieve of Atkin)

埃式筛法是一种比较新的素数筛法,它利用数学方法来筛选素数。其基本原理是找到一些模式,通过计算它们的生成公式、判别式、精度控制等方式,对素数和合数进行快速的判断和区分。

以下是使用埃式筛法实现统计素数个数的示例代码:

 C++

int countPrimes(int n) {

  if (n <= 2) return 0;

  if (n <= 3) return 1;

  vector<bool> isPrime(n, false); // 初始化所有数为合数

  int sqrt_n = int(sqrt(n));

  for (int i = 1; i <= sqrt_n; i++) {

    for (int j = 1; j <= sqrt_n; j++) {

      int num = 4*i*i + j*j;

      if (num <= n && (num % 12 == 1 || num % 12 == 5)) {

        isPrime[num] = !isPrime[num];

      }

      num = 3*i*i + j*j;

      if (num <= n && num % 12 == 7) {

        isPrime[num] = !isPrime[num];

      }

      num = 3*i*i - j*j;

      if (i > j && num <= n && num % 12 == 11) {

        isPrime[num] = !isPrime[num];

      }

    }

  }

  int count = 0;

  for (int i = 5; i < n; i++) {

    if (isPrime[i]) count++; // 统计未被筛掉的素数个数

  }

  return count + 2; // 加上 2 和 3 两个素数

}

总结:

本文介绍了 C++ 中三种常用的统计素数个数的方法,分别是埃拉托斯特尼筛法、线性筛法和埃式筛法。不同方法之间的时间复杂度和实现难度存在一定的差异,选择合适的方法可以提高计算效率。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复