C++关于质数的判定与筛法

前言:

     质数,是相伴了我们许久的老朋友,从小学到中学无处不在。

     质数,就是一个数的因子只有它自己或本身的数叫做质数。

     现在我们主要来讨论它的一些秘密。

质数的判定:

     首先是素数的判定定理:

     若从2到\sqrt{n}的数中,都没有它的约数,那么它一定是一个质数,不用解释应该就能明白,n=a*b(a<=b),则a最大为\sqrt{n}

     代码如下:

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;
    }
}

欧拉筛法:

     这是一种基于整数的唯一分解的筛法。

     因为n=p_{1}^{w1}*p_{2}^{w2}......p_{m}^{wm}只会被i=p_{1}^{w1-1}*p_{2}^{w2}......p_{m}^{wm}时被划掉。

    所以这种筛法是线性的,时间复杂度为\theta (n)

    代码如下:

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;
	}
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章