题目:
给定一个正整数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);
}