c語言輸出2~100的素數


這個代碼很巧妙,個人的理解都寫在了注釋里

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//相關的論文:[1]張景龍,黃靜,王愛松等.素數判定算法的改進[J].河南科技學院學報(自然科學版),2013,(6):61-64.DOI:10.3969/j.issn.1008-7516.2013.06.015.

//輸出100以內的素數,思路:
    //判斷素數方法1:
    //假如自然數N不是素數,則除1和其本身之外,必然至少存在兩個數A和B,使得A*B=N,
    //則A和B中必有一個大於或者等於sqrt(N),另一個小於或者等於sqrt(N)。下面是粗略證明
    //如果N是合數,則必有一個小於或者等於根號N的素因子.
    //因為任何合數都可表示為兩個或者更多個素數之積.
    //假如N是合數且其素因子都大於根號N,那么將產生矛盾:根號N*根號N>N.所以合數必有(至少)一個不大於根號N的素因子.
    //n的不大於根號的因子<=sqrt(n);n-1的不大於根號的因子<=sqrt(n-1),顯然sqrt(n-1)<sqrt(n);
    //所以2~n內的自然數的因子范圍是2~sqrt(n);換句話說2~sqrt(n)的倍數覆蓋了了2~n范圍內的合數
//數組記錄,初始化為0,判斷為合數置為1,

#define n 100
int main()
{
    int isPrim[n+1]={0};
    int i,j;

    //判斷條件中一定是是i<=sqrt(n)

    //判斷素數方法2
    //其中2-sqrt(n)(向下取整)是不是素數該咋判斷:
    //根據:判斷自然數N是不是合數,就是看2~(N-1)之間有木有數能整除N,換句話說就是2~(N-1)之間有木有數的倍數是N。
    //因為“2-sqrt(n)”中的數若是合數,它的因數肯定是在比自己小的數中產生,
    //由2判斷了3是不是合數,由2,3判斷了4是不是合數,
    //由2,3,4判斷了5是不是合數,依次類推。。。2~(sqrt(n)-1)判斷了sqrt(n)是不是合數

    //綜合以上下面的這個循環結合了以上兩種判斷素數的方法,2-sqrt(n)(向下取整)部分用的是方法2結合方法1,
    //(sqrt(n)(向下取整)+1)~n用的是方法1
    for(i=2;i<=sqrt(n);i++){
       if(isPrim[i]==0){
       //這個判斷的依據主要是方法2
       //如果不加這個判斷,那么還會對4,6,8,10的倍數進行置1,
       //因為這些倍數已經是2的倍數,已經置過1,這進行了重復的工作。
           for(j=2*i;j<=n;j+=i){//這個倍數的循環很好,學習下
                     isPrim[j]=1;
           }
       }
    }
    for(i=2;i<=n;i++){
       if(isPrim[i]==0)
              printf("%d ",i);
    }
    return 0;
}

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
//相關的論文:[1]張景龍,黃靜,王愛松等.素數判定算法的改進[J].河南科技學院學報(自然科學版),2013,(6):61-64.DOI:10.3969/j.issn.1008-7516.2013.06.015.

//輸出100以內的素數,思路:
//判斷素數方法1:
//假如自然數N不是素數,則除1和其本身之外,必然至少存在兩個數A和B,使得A*B=N,
//則A和B中必有一個大於或者等於sqrt(N),另一個小於或者等於sqrt(N)。下面是粗略證明
//如果N是合數,則必有一個小於或者等於根號N的素因子.
//因為任何合數都可表示為兩個或者更多個素數之積.
//假如N是合數且其素因子都大於根號N,那么將產生矛盾:根號N*根號N>N.所以合數必有(至少)一個不大於根號N的素因子.
//n的不大於根號的因子<=sqrt(n);n-1的不大於根號的因子<=sqrt(n-1),顯然sqrt(n-1)<sqrt(n);
//所以2~n內的自然數的因子范圍是2~sqrt(n);換句話說2~sqrt(n)的倍數覆蓋了了2~n范圍內的合數
//數組記錄,初始化為0,判斷為合數置為1,

#define n 100
int main()
{
int isPrim[n+1]={0};
int i,j;

//判斷條件中一定是是i<=sqrt(n)

//判斷素數方法2
//其中2-sqrt(n)(向下取整)是不是素數該咋判斷:
//根據:判斷自然數N是不是合數,就是看2~(N-1)之間有木有數能整除N,換句話說就是2~(N-1)之間有木有數的倍數是N。
//因為“2-sqrt(n)”中的數若是合數,它的因數肯定是在比自己小的數中產生,
//由2判斷了3是不是合數,由2,3判斷了4是不是合數,
//由2,3,4判斷了5是不是合數,依次類推。。。2~(sqrt(n)-1)判斷了sqrt(n)是不是合數

//綜合以上下面的這個循環結合了以上兩種判斷素數的方法,2-sqrt(n)(向下取整)部分用的是方法2結合方法1,
//(sqrt(n)(向下取整)+1)~n用的是方法1
for(i=2;i<=sqrt(n);i++){
if(isPrim[i]==0){
//這個判斷的依據主要是方法2
//如果不加這個判斷,那么還會對4,6,8,10的倍數進行置1,
//因為這些倍數已經是2的倍數,已經置過1,這進行了重復的工作。
for(j=2*i;j<=n;j+=i){//這個倍數的循環很好,學習下
isPrim[j]=1;
}
}
}
for(i=2;i<=n;i++){
if(isPrim[i]==0)
printf("%d ",i);
}
return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM