題目:
給定一個正整數n,計算出小於等於n的質數有多少個?比如17,則返回7,因爲小於等於17的質數有2,3,5,7,13,17。
分析:
1、首先得知道什麼是質數?
質數又稱素數,如果一個大於1的自然數,除了1和它自身外,沒法被其他自然數整除,那麼這個自然數就是質數。換句話說,只有兩個正因數(1和本身)的自然數即爲質數。
2、那麼如何判斷一個數是質數呢?
思路1:
判斷一個整數m是否是質數,只需把 m 被 2 ~ m-1 之間的每一個整數去除,如果都不能被整除,那麼 m 就是一個質數。
思路2:
m 不必被 2 ~ m-1 之間的每一個整數去除,只需被 2 ~ m−−√m之間的每一個整數去除就可以了。如果 m 不能被 2 ~ m−−√m間任一整數整除,m 必定是質數。原因:因爲如果 m 能被 2 ~ m-1 之間任一整數整除,其二個因子必定有一個小於或等於m−−√m,另一個大於或等於m−−√m。例如 16 能被 2、4、8 整除,16=2*8,2 小於 4,8 大於 4,16=4*4,4=16−−√16,因此只需判定在 2~4 之間有無因子即可。
思路3:
用空間換取時間的思想,定義一個大小爲n+1的數組(數組下標從2開始),都置爲0,表示都爲質數,然後i從2遍歷到根號n,把所有i的倍數都置爲1,最後將數組內容爲0的下標輸出來。
void count_prime(int n)
{
int *flag;
flag = (int *)malloc((n+1)* sizeof(int));
memset(flag,0,(n+1)*sizeof(int));
int i = 2,j;
while (i<=n)
{
if (!flag[i])
{
j = i;
while (i*j<n)
{
flag[i*j] = 1;
j++;
}
}
i++;
}
for(i = 2;i<=n; i++)
{
if (flag[i] == 0)
{
printf("%d\t", i);
}
}
free(flag);
}