筛检法求一定范围内的素数

#include <iostream>
#include <cctype>
#include <string>
#include <math.h>
using namespace std ;


/*1:素数筛检法:先去除偶数,再将3,5,7等的倍数去除
//求1到N中的所有素数,包含N ,参数n代表N
*/
void primeInN1(int n)
{  
if(n<=1)
return ;


bool *prime = new bool[n+1];
 memset(prime,true,sizeof(bool)*(n+1));  
     prime[0]=prime[1]=false;
//将偶数设置为false
     for(int i=3;i<=n;i++)  
        prime[i]=i%2==0?false:true; 
 
     int k=(int)sqrt(n*1.0);  


     for( i=3;i<=k;i++)  
       if(prime[i])  
         for(int j=i*2;j<=n;j+=i)  
            prime[j]=0;  


cout<<n<<"以内的素数有:\n";
for(  i = 2 ; i <= n ; i++)

if(prime[i])

cout<<i<<endl;

 delete[]prime ;

}  








//2优化后的筛法,1中原始筛法中,某个数字可能被不止一次地删去  
//   优化后的筛法就可以避免这种不必要的删去操作   


void primeInN2(int n )
{  
if(n<=1)
return ;


      bool *prime = new bool[n+1];
 memset(prime,true,sizeof(bool)*(n+1));  
     prime[0]=prime[1]=false;


     for(int i=3;i<=n;i++)  
        prime[i]=i%2==0?false:true;  
     int k=(int)sqrt(n*1.0);  //①
     for( i=3;i<=k;i++)  
       if(prime[i])  
  {
  int incre = 2*i ;
         for(int j=i*i;j<=n;j+=2*i)//优化(假设i为奇数,i+i必定为偶数(非素数),i+2i为奇数 )  ② 
            prime[j]=0;  
  }




  cout<<n<<"以内的素数有:\n";
for(  i = 2 ; i <= n ; i++)
if(prime[i])

cout<<i<<endl;

 delete[]prime ;

}  




/************************************************************************/
/* 3.该方法是对2.的改进,因为偶数必定不是素数(除了2),所以没有必要存放偶数,数组prime中存放的都是奇数。
                                                                  */
/************************************************************************/
void primeInN3(int n)
{  
if(n<=1)
return ;
else if(n==2)
{
cout<<n<<"以内的素数有:\n";
          cout<<"2"<<endl;
return ;
}
//2.中下标对应的就是对应的值,而3中下标对应的值为a[i]= 2*i+3;


    //因为prime[i]=2*i+3; 最大下标为n=偶数?(n-1-3)/2:(n-3)/2
int count =(n%2==0)?(n-4)/2:(n-3)/2;
bool *prime = new bool[count+1];
     memset(prime,true,sizeof(bool)*(count+1));  
     


     int k=count; 
//跟2中的①一样,prime[i]=2*i+3 ,n^2 = (2*i+3)-->i=(√n  -3)/2
int m = (int)( ( sqrt(n*1.0)-3 )/2 );
     for(int i=0;i<=m;i++)          
        if(prime[i])  
{
int incre = 2*i+3 ;
/************************************************************************/
/* 同2中的 ②一样:a[n]=2n+3, a[k]= 2k+3.   a[n]=(a[k])^2--> 2n+3 = (2k+3)^2
*  即n = 2*i*i + 6*i + 3.
               (2)2中的 ②中循环的递增量是2*i 即等同于3中(a[n])-a[k]=2a[k]-->
  2n+3 = 3(2k+3)-->n = 3k+3  所以n-k = 2k+3为增量
/************************************************************************/
          for(int j=2*i*i+6*i+3;j<=k;j+=incre) 
            prime[j]=false;  
}
          
 cout<<n<<"以内的素数有:\n";
          cout<<"2"<<endl;
 for ( i = 0 ; i <= count ; i++)
 if(prime[i]==true)

 cout<<(2*i+3)<<endl;


 delete[]prime ;

}  




int main()
{   
primeInN1(100);
primeInN2(80);
primeInN3(200);


return 0 ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值