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

 

 

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