素数筛

筛:开一个数组 循环一遍判断是否为素数

暴力判别

int isprime(int n){
    if(n<=1) return 0;
    if(n==2||n==3) return 1;
    for(int i=2; i<=n-1; i++)
        if(n%i==0) return 0;
    return 1;
}

埃氏筛——循环范围缩小 sqrt(n)

int isprime(int n){
    if(n<=1) return 0;
    if(n==2||n==3) return 1;
    for(int i=2; i<=sqrt(n); i++)
        if(n%i==0) return 0;
    return 1;
}

普通筛法

一开始假设都是素数
从2开始到N,依次判断,如果一个数是素数,那么把他的倍数都标记成不是素数

#include<iostream>
using namespace std;
const int N = 10000;
bool prime[N];
//是素数:true 不是素数:false
void isprime(){
    memset(prime,1,sizeof(prime));
    for(int i = 2; i<N; i++){
        if(prime[i]){
            for(int j = 2; j*i<N; j++)
                prime[i*j]=0;
        }
    }
    prime[1] = 0;
}
int main(){
    isprime();
    for(int i=1; i<100; i++)
        if(prime[i])
            cout << i << " ";
    return 0;
}

线性筛法

#include<iostream>
#include<algorithm>
#include<cstring>
#include<math.h>
using namespace std;
#define M 10000

int pnum[M+5];
bool prime[M+5];

void isprime(){
    int t=1;
    //是素数:prime是true 不是:0
    memset(prime,1,sizeof(prime));
    prime[0] = prime[1] = 0;
    for(int i=2; i<=M; i++){
        if(prime[i]){
            pnum[t++] = i;
        }
        //乘上系数
        for(int j=1; j<=t && i*pnum[j]<=M; j++){
            prime[i*pnum[j]]=0;
            //prime是这个合数的最小质因子
            // i有比prime[j]更小的质因子,或者超出n的范围
            if( i % pnum[j]==0 ) break;
        }
    }
}
int main(){
    isprime();
    for(int i=0; i<100; i++){
        if(prime[i]) cout << i << " ";
    }
    
    return 0;
}


避免重复被筛
上面的算法
eg:6 会被2 和3 各筛一次
开一个数组保存目前为止所筛出来的素数,当i被判断是素数,存入,并且把这个数组里所有i倍的数都标记为非素数

I=2:

prime[2]=true;
pnum[0]=2;------t=1

pnum[0]*2 = 4 -> prime[4]=false;

I=3;

prime[3]=true;
pnum[1] = 3;

pnum[0]*3 =6 -> prime[6] = false;
pnum[1]*3 = 9 ->prime[9] = false;

I=4;

prime[4] = false;

pnum[0]*4 = 8 -> prime[8] = false;
pnum[1]*4 = 12 ->prime[12] = false

1 x
2 v
3 v
4x
5
6x
7
8x
9x
10

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值