欧拉筛法:c作业5有关素数的补充

每日小语:

失去了很多东西,才发现自己并非一无所有。——《神的记事本》

欧拉筛法内容:

欧拉筛法(Euler's Sieve)是一种高效的筛法算法,用于筛选出一定范围内的所有素数。该算法以数学家欧拉的名字命名,由欧拉首先提出。

欧拉筛法的主要思想是基于质数的倍数一定不是素数的性质。算法的步骤如下:

  1. 初始化一个布尔数组 primes[],将所有数都标记为素数(primes[i] = true)。

  2. 从2开始遍历到N,对于每个数 i,如果它是素数(即 primes[i] = true),则将它的倍数(除了它本身)都标记为非素数(primes[j] = false)。

  3. 遍历结束后,primes[] 数组中为 true 的索引对应的数即为素数。

以下是一个使用欧拉筛法查找范围内的素数的示例代码:

#include <stdio.h>
#include <stdbool.h>

#define MAX_NUM 100

void eulerSieve(bool primes[], int n) {
    // 将primes数组初始置为true,表示所有数都是素数
    for (int i = 2; i <= n; ++i) {
        primes[i] = true;
    }

    // 利用筛法,标记非素数
    for (int p = 2; p * p <= n; ++p) {
        if (primes[p] == true) {
            // 将p的倍数标记为非素数
            for (int i = p * p; i <= n; i += p) {
                primes[i] = false;
            }
        }
    }
}

int main() {
    bool primes[MAX_NUM + 1];

    eulerSieve(primes, MAX_NUM);

    for (int i = 2; i <= MAX_NUM; ++i) {
        if (primes[i]) {
            printf("%d ", i);
        }
    }
    printf("\n");

    return 0;
}

在以上示例代码中,我们使用 eulerSieve 函数来执行欧拉筛法,接收一个布尔数组 primes 和一个整数 n,并将 primes 数组中的元素设置为 true 或 false,表示对应的数是否为素数。最后,我们遍历 primes 数组,输出为 true 的索引对应的值,即素数。

分步拆解:

1.首先,我们定义了一个布尔数组 primes,数组大小为 MAX_NUM + 1,其中 MAX_NUM 定义了要寻找素数的上限。

#define MAX_NUM 100

void sieveOfEratosthenes(bool primes[], int n) {
    // 将primes数组初始置为true,表示所有数都是素数
    for (int i = 2; i <= n; ++i) {
        primes[i] = true;
    }

2.然后,我们调用 sieveOfEratosthenes 函数来执行埃拉托斯特尼筛法。该函数接收一个布尔数组 primes 和一个整数 n,并根据埃拉托斯特尼筛法的原理,将 primes 数组中的元素设置为 true 或 false,表示对应的数是否为素数。

在 sieveOfEratosthenes 函数中,我们首先将 primes 数组初始化为 true,表示所有数都是素数。

接下来,通过两重循环,我们遍历 p 从 2 到 sqrt(n),其中 p 表示当前的质数。对于每个质数 p,我们将其倍数 p*pp*p + pp*p + 2p等,都标记为非素数,即将对应位置的 primes 值设置为 false

// 利用筛法,标记非素数
    for (int p = 2; p * p <= n; ++p) {
        if (primes[p] == true) {
            // 将p的倍数标记为非素数
            for (int i = p * p; i <= n; i += p) {
                primes[i] = false;
            }
        }
    }
int main() {
    bool primes[MAX_NUM + 1];
    
    sieveOfEratosthenes(primes, MAX_NUM);

    printf("2 ");
    for (int i = 3; i <= MAX_NUM; i += 2) {
        if (primes[i]) {
            printf("%d ", i);
        }
    }
    printf("\n");

    return 0;
}

思考:

相同点:都是通过类似IsPrime这样的变量的改变值来判断。

不同点:欧拉筛法更省时省力,他抓住的问题的本质更细致。

欧拉筛法(Euler's Sieve)相较于其他素数筛法的优势主要在于其时间复杂度较低,具有以下几个好处:

1. 效率高:欧拉筛法在找出一定范围内的素数时具有较低的时间复杂度,约为 O(n) 或 O(nlog(logn))。相比于其他素数筛法,如试除法或埃拉托斯特尼筛法,欧拉筛法在大规模素数的筛选中速度更快。

2. 空间利用率高:与埃拉托斯特尼筛法不同的是,欧拉筛法仅使用一个布尔数组来标记素数和非素数,而不需要额外的存储空间。这使得欧拉筛法在处理大规模的素数筛选时所需的内存占用更低。

3. 可以高效地生成筛选后的素数列表:欧拉筛法通过标记非素数,最终留下来的为素数的数值。这使得我们可以高效地生成筛选后的素数列表,而无需进行额外的判断和操作。

4. 算法简单易实现:欧拉筛法的算法逻辑相对简单,易于理解和实现。通过两重循环,根据质数的倍数进行标记,即可找出范围内的素数。这使得欧拉筛法成为一种常用的素数筛选方法。

时间复杂度目前还不知道是什么,啊,还是得自己敲一遍。但我真的不想敲了呜呜,到饭点了,下次一定,撒花撒花。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值