赞
踩
要筛选出以内的素数,一般有两种方法,一个是埃氏筛法,另一个是欧拉筛法。埃氏筛法就是从
开始每次去除素数
的倍数,在完成了一次去除后剩下的最小的数字就是一个素数,又可以从它开始去除它的倍数的数字了,这样一直到
(是素数或者是被去除的数)为止。因为某个数总是素数的乘积,所以合数都会被去除。C++代码可以这样写:
- //埃氏筛法
- bool *primes(int n){
- bool *p=(bool *)malloc(sizeof(bool)*(n+1));
- memset(p,true,n+1);
- p[0]=p[1]=false;
- for(int i=2;i<=n;){
- int j=i*i;
- while(j<=n){
- p[j]=false;
- j+=i;
- }
- while(!p[++i]);
- }
- return p;
- }
不过这种算法时间复杂度为,欧拉筛法的时间复杂度为 线性阶的,因而它又被称为线性筛法。
线性筛法的大致过程可以描述如下:
通过欧拉筛法,可以去掉合数,筛选出质数,这是因为:
(1)对于一个合数,若
,而
和
为小于
的质数,则
一定被去掉。否则,则有
,
是是
的最小质因数,取
的最小质因数成立,
。
(2)在上述筛法中,对于,若存在
使
,则有
,又
,
矛盾,因此不存在这样的,所以
已被去除。
而线性筛法,大致可以用如下的C++代码描述:
- #include<iostream>
- using namespace std;
- const int N=100000010;//我的机器上int为4个字节
- int vis[N];
- int prim[N];
- int cnt;
-
- void get_prim(int n){
- for(int i=2;i<=n;i++){
- if(!vis[i])prim[++cnt]=i;
- for(int j=1;1ll*i*prim[j]<=n;j++){
- vis[i*prim[j]]=1;
- if(i%prim[j]==0)break;
- }
- }
- }
-
- int main(){
- int n;
- cin>>n;
- get_prim(n);
- for(int i=1;i<=cnt;i++){
- cout<<prim[i]<<" ";
- }
- return 0;
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。