1. 程式人生 > >素數篩選法 (求1~n的素數)

素數篩選法 (求1~n的素數)

1、下面是求1~n的素數的一般方法:

//求1~n的素數一般方法
#include<iostream>
using namespace std;
int main()
{
   int n,i,j,k=1;
   bool bo;
   cin>>n;cout<<"2 ";
     for (i=3;i<=n;i+=2)
	{
	   bo=true;
           for (j=3;j*j<=i;j+=2)
            if (i%j==0)
	     {
	       bo=false;
	       break;
	     }
	       if (bo)
		 {
	           if (k%10==0) cout<<endl;
		    cout<<i<<' ';
		      k++;
	         }
	}
      cout<<endl<<k<<endl;
  return 0;
}

2、對於素數篩選法,具體方法就不闡述了,百度一下就能找到,簡單地說就是找到一個素數就把它的倍數標記為非素數。

參考程式碼:

//素數篩選法求1~n的素數
#include<iostream>
using namespace std;
#define N 1000000000
  bool isprime[N];
  int prime[100000];
int main()
{
	int n,i,j,k=1;
	memset(isprime,true,sizeof(isprime));
	   cin>>n;
	     int num=0;
		   prime[num++]=2;
     	        for (i=3;i<=n;i+=2)
		   {
		      if (isprime[i])
			   {
			      prime[num++]=i;
				for (j=i+i;j<=n;j+=i)  
				   isprime[j]=false;
			   }
		   }
		   for (i=0;i<num;i++)
		   {
	             cout<<prime[i]<<' ';
		       if ((i+1)%10==0)
         		  cout<<endl;
		   }
      cout<<endl<<num<<endl;
  return 0;
}

3、下面是我對演算法的小小的優化:

 

         就是將   for ( j=i+i ; j<=n ; j+=i )   改成    for ( j=i*i ; j<=n ; j+=2*i )   因為2*i是2的倍數,3*i是3的倍數,5*i是5的倍數~~~~~~,所以 j 直接從 i*i 開始;而每次j 自加2*i ,

這樣可以把偶數給排除掉。修改後可以減少一部分的重複賦值。

完整程式碼:

#include<iostream>
using namespace std;
#define N 1000000000
  bool isprime[N];
  int prime[100000];
int main()
{
	int n,i,j,k=1;
	memset(isprime,true,sizeof(isprime));
	   cin>>n;
	     int num=0;
	       prime[num++]=2;
     	   for (i=3;i<=n;i+=2)
	     {
	       if (isprime[i])
	         {
		    prime[num++]=i;
		      for (j=i*i;j<=n;j+=2*i)
			 isprime[j]=false;
	         }
	     }
	  for (i=0;i<num;i++)
	    {
	      cout<<prime[i]<<' ';
	         if ((i+1)%10==0)
	           cout<<endl;
	    }
      cout<<endl<<num<<endl;
  return 0;
}