一:暴力求解(直接根据素数的定义)
//返回1:是素数;返回0:非素数
int isPrime(int n)
{
int i;
if(n<2) return 0;
for(i=2;i<n;i++)
if(n%i==0) return 0;
return 1;
}
然而想要通过此方法快速获得10000000以内的素数总数的话,难......
二:除去部分因数求解(平方根和偶数助力)
首先,能被2整除的数----非素数;
其次,举例数36,开方得6。好,我们来看看25可以分解成哪些因数。
正序来看,36=1*36=2*18=3*12=4*9=6*6;
反序来看,36=36*1=18*2=12*3=9*4=6*6;
再举一个例,24,开方不能得到一个整数,近似于4或5,设为x(较小值)和y(较大值);
正序来看,24=1*24=2*12=3*8=4*6
反序来看,24=24*1=12*2=8*3=6*4
举这两个例子是想说明要是我们在判断某数是否为素数时,如果在判断某数如果除以它的平方根后依旧不能被整除,那么就可判断该数为素数;
像24的平方根不是整数时,使用sqrt函数不能确保某数开方得到的是x还是y,那么判断范围扩大到sqrt函数得到的数+1即可确保。
int isprime(int n)
{
int i;
if(n==2) return 1;
else if(n<2 || n%2==0) return 0;
else
for(i=3;i<=sqrt(n)+1;i+=2)
if(n%i==0) return 0 ;
return 1;
}
三:制表法进阶(开一个内存,利用指针)
设某数x,如果判断到x的质因数为a,b,c.......那么此时将凡是a,b,c....的倍数均做上标记;
下次遇见直接跳过;
不可避免地需要使用数组。但如果想开容量很大的数组(如10000000),编译器不能接受?(...猜测溢出?)
所以尝试使用指针;
int prime(int n)
{
int counts;
int i;
//使用指针
unsigned char *prime =(unsigned char*)malloc(n+1);
for(i=2;i<n;i++)
prime[i]=1;
for(i=2;i<=n;i++)
{
if(prime[i])
{
counts++;
for(int j=i+i;j<n;j+=i)
prime[j]=0;
}
}
free(prime);
printf("%d",counts);
return 0;
}
原文地址:https://www.cnblogs.com/JaneLin0409/p/12237290.html