素数筛选

素数筛选目的是筛选出某一区间[m, n)内的所有素数,常见方法包括如下几种:

1.朴素的筛选法:

先写出判断函数isPrime(),再对区间内的数依次调用isPrime()进行判断,算法核心是以2~根号n作为除数。

#include <math.h>

bool isPrime(int n)
{
    /*
        C++中sqrt有两个重载函数,参数可以是double或float,由于传入参数是int,在默认的隐式类型转换中int可以
        转换成float也可以转换为double,则须通过强转告诉编译器该调用哪一个函数。
    */
    int sqr = (int)sqrt(double(n));
    for(int i = 2; i <= sqr; i++)
    {
        if(n%sqr == 0)
            return false;
    }
    return true;
}

2.高效的筛选法之一:

借助标记数组,对于2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23……初始时均标记素数,模拟如下剔除合数的过程:

从区间首部开始往后依次考察,如果当前m被标记为素数,那么2*m, 3*m, 4*m……都要标记为合数;如果m被标记为合数,则跳过继续考察m+1……当整个区间全部考察完后,所有素数和合数对照标记数组一目了然。

   考察2时:2,3,5,7,9,11,13,15,17,19,21,23……;

   考察3时:2,3,5,7,11,13,17,19,23……;

   考察4时:直接跳过,因为其后如果有4的倍数而作为合数被剔除,那么在考察2时就已执行,此时已无意义;

   考察5时:2,3,5,7,11,13,17,19,23……;

   ……

这种算法的核心思想:

如果在考察到某一个数时,发现它仍然没有在前面多轮剔除合数的过程中被剔除掉,那么它不是此前任何数的倍数,即必定是素数;

接下来剔除其后与其成倍的数,因为这个剔除过程并不是前面某个剔除过程的子集,所以必定有意义。

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 100

bool isPrime[N+2];

void process()
{
    int i, j;
    memset(isPrime, true, sizeof(isPrime));
    for(i=2; i<=N; i++)
    {
        if(isPrime[i])
        {
            for(j=i+i; j<=N; j+=i)
                isPrime[j] = false;
        }
    }
}

int main()
{
    process();
    for(int k=2; k<=N; k++)
    {
        if(isPrime[k])
            cout << k << " ";
    }
    return 0;
}

3.高效的筛选法之二

从区间首部开始遍历,并始终维护一个当前已找到素数的集合,如果当前考察数据都不能被素数集合中的数整除,则作为素数将其加入集合中……依次迭代到区间末尾,最终集合即为结果。

#include <stdio.h>
#include <string.h>
#include <iostream>
using namespace std;
#define N 100

int prime[N+2];
int pLen;

void setPrime()
{
    prime[0] = 2;
    pLen = 1;

    bool isPrime;
    for(int i=3; i<=N; i++)
    {
        isPrime = true;
        for(int j=0; j<pLen; j++)
        {
            if(i%prime[j] == 0)
            {
                isPrime = false;
                break;
            }
        }
        if(isPrime)
            prime[pLen++] = i;
    }
}

int main()
{
    setPrime();
    for(int k=0; k<pLen; k++)
    {
        cout << prime[k] << " ";
    }
    return 0;
}
原文地址:https://www.cnblogs.com/1203ljh/p/4640958.html