C++关于质数的判定与筛法
前言:
质数,是相伴了我们许久的老朋友,从小学到中学无处不在。
质数,就是一个数的因子只有它自己或本身的数叫做质数。
现在我们主要来讨论它的一些秘密。
质数的判定:
首先是素数的判定定理:
若从2到的数中,都没有它的约数,那么它一定是一个质数,不用解释应该就能明白,n=a*b(a<=b),则a最大为
。
代码如下:
for(int i=2;i*i<=n;i++)//n为待判定数,x为1,则n不是质数。
{
if(n%i==0)
{
x=1;
break;
}
}
质数定理(Gauss & Legendre):
n充分大时,n以内的素数个数约等于n/logn个。(仅做了解,并不具体说明)。
质数的筛法:
下面是对快速求1~n的质数的筛法的介绍。
埃拉托斯特尼筛法:
相信大家并不对此感到陌生,就是划倍数的那个方法(在代码时,在做具体讲解)。
我们现在来讨论它的时间复杂度。
显然这里是存在被划掉许多次的数,如18,就会被2和3划两次。
所以这种筛法并不是线性的。
时间复杂度就是:
代码如下:
for(int i=2;i<=n;i++)//枚举从2至N的正整数。
{
if(!v[i])
{
k++;
pr[k]=i;//pr存储质数
for(int j=i*i;j<=n;j+=i)//枚举i的倍数。
v[j]=1;
}
}
欧拉筛法:
这是一种基于整数的唯一分解的筛法。
因为只会被
时被划掉。
所以这种筛法是线性的,时间复杂度为。
代码如下:
for(int i=2;i<=x;i++)
{
if(!v[i])
{
v[i]=1;
k++;
pr[k]=i;
}
for(int j=1;j<=k&&pr[j]*i<=x;j++)
{
v[pr[j]*i]=1;
if(i%pr[j]==0)
break;
}
}