如何判斷一個數是否是質數(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的自然數如果它不是合數,則它是質數。也就是說
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> 先將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;
}