判断素数时间比较
一.用朴素法判断素数与用欧拉函数判断素数的时间比较
Ps:如果N是素数,则有Euler(N)+1=N.
代码如下:
#include<stdio.h>
#include<time.h>
#include<math.h>
#define MAX 10000000
int Euler(int n)
{//欧拉函数
int ret=n,i;
for(i=2;i*i<=n;i++)
if(n%i==0)
{
ret=ret-ret/i;
while(n%i==0)
n/=i;
}
if(n>1) ret=ret-ret/n;
return ret;
}
bool Prime(int n)
{//朴素法判断素数
int i,j,k;
for(i=2;i<=sqrt(n*1.0);i++)
if(n%i==0)
return false;
return true;
}
int main()
{
clock_t start,end;
int N=MAX;
double sum_1=0,sum_2=0;
while(N--)
{
start=clock();
Euler(N);
// if(Euler(N)+1==N)
// printf("YES\n");//是素数
// else
// printf("NO\n");//不是素数
end=clock();
sum_1+=(end*1.0-start*1.0)/CLOCKS_PER_SEC;
start=clock();
Prime(N);
// if(Prime(N)==true)
// printf("YES\n");//是素数
// else
// printf("NO\n");//不是素数
end=clock();
sum_2+=(end*1.0-start*1.0)/CLOCKS_PER_SEC;
}
printf("Euler:%lfms Prime:%lfms\n",sum_1,sum_2);
return 0;
}
代码第四行中MAX取1~10^7,即运行次数。
Euler()表示欧拉函数法。
Prime()表示朴素法。
1)当MAX取1~1000时,两种方法的运行时间都接近0ms,下图是MAX为1000时的运行时间。
2)当MAX取10000时,运行了几次,用时有时用Euler()快,有时Prime()快,有时都接近0ms,所以让程序运行了N次,下面是结果。
N\num\time Euler()<Prime() Euler()=Prime() Euler()>Prime()
100
1000
10000
※Euler()<Prime()表示用欧拉函数运行时间比朴素法短,后边Euler()=Prime()与Euler()>Prime()类似;N表示程序让Euler()或Prime运行了N次;num表示运行N次个情况出现的次数。
3)当MAX取10^5时,运行时间如下图。
4)当MAX取10^6时,运行时间如下图。
5)当MAX取10^7时,运行时间如下图。
结论:由以上数据可以看出,当运行次数不太大时,即MAX小于10000时,两种方法都接近0秒,差别不大,当MAX大于10000时,差距就显现出来,而且数据越大,差距越明显。
二.厄拉多塞筛法与朴素法判断素数
数据大时不用怀疑,肯定要用筛法,这不用说。
下面是对1~MAX素数的打表所用时间和用朴素法判断N(N不大于100)个MAX是否是素数所用的时间。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<time.h>
#define MAX 100000000
int a[MAX+10];
void Fun()
{//厄拉多塞筛法
int i,j;
memset(a,0,sizeof(a));
for(i=2;i<=sqrt(MAX*1.0);i++)
for(j=2*i;j<=MAX;j+=i)
if(a[j]==0)
a[j]=1;
}
bool Prime(int n)
{//朴素法
int i;
for(i=2;i<=sqrt(n*1.0);i++)
if(n%i==0)
return false;
return true;
}
int main()
{
clock_t start,end;
int N=100;
double sum_1=0,sum_2=0;
{
start=clock();
Fun();
end=clock();
sum_1+=(end*1.0-start*1.0)/CLOCKS_PER_SEC;
start=clock();
while(N--)
Prime(MAX);
end=clock();
sum_2+=(end*1.0-start*1.0)/CLOCKS_PER_SEC;
printf("Fun:%lfms \nPrime:%lfms \n",sum_1,sum_2);
}
return 0;
}
1)当MAX取10^5时运行时间如下图。
这说明筛法筛10^5个左右数时用时接近0ms。
2)当MAX取10^6时运行时间如下图。
3)当MAX取10^7时运行时间如下图。
总结:当只判断数目不大的N个数是否是素数时,朴素方法比筛法快。