采用三种方法计算质数,并比较运行时间
#include<iostream> #include<time.h> #include<vector> using namespace std; #define N 100000000 char a[N/8+1]; class Time { clock_t clockBegin; clock_t clockEnd; public: void Start() { clockBegin = clock(); } int End() { clockEnd = clock(); return clockEnd - clockBegin; } int Interval() { return clockEnd - clockBegin; } }; void SetBit(int i,bool tf) { int x=i&7; int index=i>>3; if(tf) { a[index]=a[index]|(1<<(x)); } else { a[index]=a[index]&(~(1<<(x))); } } bool GetBit(int i) { int x=i&7; int index=i>>3; if(a[index]&(1<<(x))) { return true; } else return false; } // 通过质数进行帅选的优化方法 void FilterMethod1() { int i; int count=0; int currentIndex=2; // 进行帅选的起始值,从最小的质数2开始 memset(a,0xff,sizeof(a)); i=currentIndex; for(;i<=sqrt(N);) // 进行筛选的数最大是根号N { int j=2; while(j*i<=N) // 把所有i的倍数肯定不是质数 { SetBit(j*i,false); j++; } int k=i+1; //搜素[i+1,i*i]的区间,这个区间的质数是已经被算出来的,在这个区间中找出下一个质数 while(k<=i*i) { if(GetBit(k)) // 不为零,说明是质数 { break; } k++; } i=k; // 用搜索到的质数进行筛选 } for(i=2;i<=N;i++) // 这里1不是质数 { if(GetBit(i)) { count++; } } cout<<"\nFilterMethod1计算出质数量="<<count<<endl; cout<<endl; } // 普通的筛选方法 void FilterMethod2() { int i; int count=0; memset(a,0xff,sizeof(a)); for(i=1;i<=N;i++) { SetBit(i,true); } for(i=2;i<=N/2;i++) { int j=2; while(j*i<=N) { SetBit(j*i,false); j++; } } for(i=2;i<=N;i++) // 这里1不是质数 { if(GetBit(i)) { count++; } } cout<<"\nFilterMethod1计算出质数量="<<count<<endl; cout<<endl; } // 采用除法计算质数 void DivMethod() { int i; vector<int> vec; vec.push_back(2); for(i=3;i<=N;i++) { int j; int iSqrt=sqrt(i); for(j=0;j<vec.size()&&j<=iSqrt;j++) // 不计算1 { if(i%vec[j]==0) { break; } } if(j>=vec.size()||j>iSqrt) { vec.push_back(i); } } cout<<"\nDivMethod1计算出质数量="<<vec.size()<<endl; cout<<endl; } int main() { Time tFilter; tFilter.Start(); FilterMethod1(); tFilter.End(); cout<<"采用质数优化的方法:"<<tFilter.Interval()<<"毫秒"<<endl; tFilter.Start(); FilterMethod2(); tFilter.End(); cout<<"普通筛选法:"<<tFilter.Interval()<<"毫秒"<<endl; tFilter.Start(); DivMethod(); tFilter.End(); cout<<"试除法:"<<tFilter.Interval()<<"毫秒"<<endl; system("pause"); return 0; }