素数筛思想

Posted buling_buling_

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了素数筛思想相关的知识,希望对你有一定的参考价值。

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

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

我们不难注意到,对于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;
}

在这里插入图片描述

以上是关于素数筛思想的主要内容,如果未能解决你的问题,请参考以下文章

素数筛法(Eratosthenes筛法)

素数筛(筛选出一定范围内的所有素数)

洛谷 P1865 A % B Problem[筛素数/前缀和思想/区间质数个数]

算法杂谈埃氏素数筛

素数筛法

三 数论的编程实验