素数筛思想

本文介绍了一种使用素数筛法来找出指定范围内所有素数的方法。通过标记非素数,仅保留素数,该算法有效地实现了素数的快速筛选。文章详细解释了算法原理并提供了实现代码。

采用素数筛的方式求解输入的两个值之间的所有素数

筛法的思想是”标记出所有非素数,输出所有没有被标记的数字*

我们不难注意到,对于n以内的筛选来说,如果n 是合数,c 为n的最小正因数,则有:

在这里插入图片描述
根据基本数论,我们只要找到c 就i可以确定n 是合数,并将n 进行标记。
所以可以声明一个 mark 数组,用于标记所有的素数。首先将1 和 0 对应的位置都标记为1(标记的值标是假),也就是说我们知道他们必然不是素数。而对后面所有待筛的数字都标记为0.
已知 2 是最小的素数,所以for 循环中,将2作为第一个正因数,开始筛选:

#include <stdio.h>
#include <string.h>

int n = 1000000;
int mark[1000001];
int m;
int main() {
    int c;
    int j;
    memset(mark, 0, sizeof(mark));
    mark[0] = 1;
    mark[1] = 1;
    scanf("%d%d",&n,&m);
    for (c = 2; c * c <= n; c++) {
        if (mark[c] != 1){//确保当前我们选的正因数c是一个素数时,才去用它进行非素数标记
            for (j = 2; j <= n / c; j++){//for 循环遍历了我们带排查所有因数是c 的合数,并将它们都在mark数组中都标记上1
                mark[c * j] = 1;
            }
        }
    }
    // 通过这种标记,mark数组中是1的元素的索引都是非素数了,接下来将所有标记为0的元素索引都输出即可。
    for (c = m; c <= n; c++){//这里复用了变量c 作为循环变量。
        if (mark[c] != 1){
            printf("%d\n", c);
        }
    }
    return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值