寻找N以内的素数(《编程珠玑(续)》第1章)

来源:互联网 发布:长春学历网络教育 编辑:程序博客网 时间:2024/06/06 17:41

下面给出了六段程序,分别是求N以内素数的算法的不断改进,从2s到1ms。

P1:用prime计算素数,时间2.019s

#include<iostream>#include<ctime>using namespace std;int prime(int n){for(int i=2;i<n;i++)if(n%i==0)return 0;return 1;}int main(){const int N=100000;clock_t start,end;start=clock();for(int i=2;i<=N;i++)if(prime(i));end=clock();cout<<end-start<<endl;system("pause");return 0;}
P2:用开方,舍去大部分的求值,时间:0.241s

#include<iostream>#include<ctime>using namespace std;int root(int n){return sqrt(float(n));}int prime(int n){for(int i=2;i<root(n);i++)if(n%i==0)return 0;return 1;}int main(){const int N=100000;clock_t start,end;start=clock();for(int i=2;i<=N;i++)if(prime(i));//cout<<i<<endl;end=clock();cout<<end-start<<endl;system("pause");return 0;}

如果舍去函数root调用的时间,则可以缩短到0.166s

int prime(int n){for(int i=2;i<sqrt(float(n));i++)if(n%i==0)return 0;return 1;}

P3:把sqrt从for循环中提出来,则时间变为0.023s

#include<iostream>#include<ctime>using namespace std;int root(int n){return sqrt(float(n));}int prime(int n){int bound=root(n);for(int i=2;i<bound;i++)if(n%i==0)return 0;return 1;}int main(){const int N=100000;clock_t start,end;start=clock();for(int i=2;i<=N;i++)if(prime(i));//cout<<i<<endl;end=clock();cout<<end-start<<endl;system("pause");return 0;}

P4:通过测试对2,3,5整除的数来减少开方运算,时间0.016s

#include<iostream>#include<ctime>using namespace std;int root(int n){return sqrt(float(n));}int prime(int n){if( (n!=2 && n%2==0) || (n!=3 && n%3==0) || (n!=5 && n%5==0))return 1;int bound=root(n);for(int i=7;i<bound;i++)if(n%i==0)return 0;return 1;}int main(){const int N=100000;clock_t start,end;start=clock();for(int i=2;i<=N;i++)if(prime(i));//cout<<i<<endl;end=clock();cout<<end-start<<endl;system("pause");return 0;}

P5:把开方运算换成乘法运算,时间:0.014s

#include<iostream>#include<ctime>using namespace std;int prime(int n){if( (n!=2 && n%2==0) || (n!=3 && n%3==0) || (n!=5 && n%5==0))return 1;for(int i=7;i*i<n;i++)if(n%i==0)return 0;return 1;}int main(){const int N=100000;clock_t start,end;start=clock();for(int i=2;i<=N;i++)if(prime(i));//cout<<i<<endl;end=clock();cout<<end-start<<endl;system("pause");return 0;}

P6、埃氏筛选法,算法复杂度约nloglogn,大约为O(n),耗费时间:0.001s

先把x中所有数置1,然后如果不是素数就置0。

#include<iostream>#include<ctime>using namespace std;int main(){const int N=100000;clock_t start,end;char x[N+2];for(int i=0;i<N+2;i++)x[i]=1;x[1]=0;int p=2;start=clock();while(p<=N){//cout<<p<<endl;for(int i=(p>>1);i<N;i+=p)x[i]=0;while(x[++p]==0);}end=clock();cout<<end-start<<endl;system("pause");return 0;}


0 0
原创粉丝点击