1. 程式人生 > >如何判斷一個數是否是質數(C語言)-超詳細

如何判斷一個數是否是質數(C語言)-超詳細

質數是只能被1或者自身整除的自然數(不包括1),稱為質數。

判斷是否是質數最直觀和簡單的方法就是從2開始直接除,能除盡(餘數為0)就不是質數。則C語言實現為:

int isprime(int m)

{

    int i;

    for(i=2;i<m;i++)

      if(m%i==0)

        return 0;

      else

        return 1;

}

該演算法的時間複雜度O(n)。

可以改進一下,根據如果一個數是合數,那麼它的最小質因數肯定小於等於它的平方根。用反證法可以證明一下。假設x是n的最小質因數,則存在n/x=p。p>x,x*p=n。如果x不小於等於它的平方根,則x*x>n,而p>x,故x*p>n,假設不成立。合數是與質數相對應的自然數。一個大於1的自然數如果它不是合數,則它是質數。也就是說

如果一個數能被它的最小質因數整除的話,那它肯定是合數,即不是質數。所以判斷一個數是否是質數,只需判斷它是否能被小於它開跟號後的所有數整除,因此,這樣做的運算少了很多,降低了時間複雜度。C語言實現

int isprime(int m)

{

    int i;

    for(i=2;i<=sqrt(m);i++)    /*sqrt(int n)這個函式需要引入math.h標頭檔案*/

      if(m%i==0)

        return 0;

      else

        return 1;

}

時間複雜度O(根號n) 

上面兩種方法是最常見的。如果要判斷一個範圍內的數是否是質數,則需要多次呼叫isprime()函式,時間複雜度變為增加O(n*m)或O(n*跟號m).這時,可以採用另一種稱為“埃拉托色尼(Eratosthenes)

篩法”的方法。埃拉托色尼是古希臘的著名數學家。他採取的方法是,在一張紙上寫上1到100全部整數,然後逐個判斷它們是否是素數,找出一個非素數,就把它挖掉,最後剩下的就是素數。具體做法如下:

<1> 先將1挖掉(因為1不是素數)。
<2> 用2去除它後面的各個數,把能被2整除的數挖掉,即把2的倍數挖掉。
<3> 用3去除它後面的各數,把3的倍數挖掉。
<4> 分別用4、5…各數作為除數去除這些數以後的各數。這個過程一直進行到在除數後面的數已全被挖掉為止。

如上演算法可表示為:
<1> 挖去1;
<2> 用剛才被挖去的數的下一個數p去除p後面各數,把p的倍數挖掉;
<3> 檢查p是否小於n^2的整數部分(如果n=1000, 則檢查p<31?),如果是,則返回(2)繼續執行,否則就結束;
<4> 紙上剩下的數就是素數。

這是個典型的用空間換時間的演算法。

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {

        int i,j,n;
        int num = 100;  /*1-100之內的質數,如果求1-10000之間的質數,則num=10000*/
        int a[101];  /*陣列多定義一個元素是為了讓下標和數一一對應,因為陣列下標是從0開始的*/
        for(int i=0; i<=101; i++) {
                a[i] = i;
        }      /*初始化陣列*/
        a[1] = 0;   /*1不是質數*/
        for (i=2; i<sqrt(num); i++) {
                for (j=i+1; j<=num; j++) {
                        if (a[j]!=0 && a[j]%i==0) {    /*如果是質數了,則不需要再判斷*/
                                a[j] = 0;    /*a[j]不是質數,故a[j]=0*/
                        }
                }
        }  / *依次判斷是不是2的倍數,3的倍數,4的倍數。。。。。。。。*/

        for(i=1,n=0; i<=100; i++) {
                if (a[i] != 0) {
                        printf("%d\t", a[i]);
                        if(++n%10 == 0) {
                                printf("\n");
                        }
                }
        }      /*輸出a[i]不為0的數(即質數)*/
        printf("\n");
        return 0;
}