质数筛法-线性筛法

质数筛

质数筛法是一种用于求解质数的算法。它的基本思想是:假设要求解的范围是[1,n],则从2开始,将所有2的倍数标记为合数,然后再从3开始,将所有3的倍数标记为合数,依次类推。在这个过程中,未被标记的数即为质数。

具体的实现可以使用一个数组来存储每个数是否被标记为合数,并从小到大遍历数组元素,如果该元素未被标记,则将其所有的倍数标记为合数。

下面是质数筛法的实现代码:

int prime[N], cnt = 0;//存储所有的质数和质数的个数
bool st[N];//标记每个数是否为合数

void get_primes(int n) {
    for (int i = 2; i <= n; i++) {
        if (!st[i]) {//如果i未被标记为合数,则它是质数
            prime[cnt++] = i;//将它存储在prime数组中
            for (int j = i + i; j <= n; j += i) {//将i的倍数标记为合数
                st[j] = true;
            }
        }
    }
}

该算法时间复杂度为O(nloglogn),空间复杂度为O(n),是求解质数的常用算法之一。

线性筛

线性筛是一种用于求解素数的算法,其时间复杂度为O(n)。相比传统的试除法,线性筛的优势在于可以避免重复的除法运算,从而提高效率。

算法步骤如下:

  1. 申请一个数组is_prime[],用于保存是否为素数的标记,初始值全部设置为true。

  2. 从2开始遍历到n,每遇到一个素数p,就将is_prime[p]设置为true,并从2p开始,将is_prime的倍数全部标记为false。

  3. 遍历完成后,is_prime数组中的true值即为1~n中的所有素数。

示例代码如下:

void linear_sieve(int n) {
    vector primes;  // 保存素数
    vector is_prime(n+1, true);  // 初始全部为素数
    for (int i = 2; i <= n; i++) {
        if (is_prime[i]) {
            primes.push_back(i);
        }
        for (int j = 0; j < (int)primes.size() && i * primes[j] <= n; j++) {
            is_prime[i * primes[j]] = false;
            if (i % primes[j] == 0) {
                break;
            }
        }
    }
}

你可能感兴趣的:(c++那些算法,算法,开发语言,c++)