下面给出了六段程序,分别是求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;
}