额,先引入一下
如何求一个数是不是素数:
目前的方法就是从2到这个数的平方根挨个尝试,看是否有能整除的:
bool Is_Prime(int a){
if(a <= 1){
return 0;
}
int bound = (int)sqrt(a) + 1;
for(int i = 2;i < bound;i++){
if(a % i == 0){
return 0;
}
}
return 1;
}
但如果要求的数有点多的话,这种方法显然不行;
1.关于埃氏的筛法
看起来很简单,就是将素数的倍数筛去(像一个筛子一样的),剩下的就是素数了;
void Eratosthenes(int n)
{
memset(isprime,1,sizeof(is_prime));
is_prime[1]=false;
int k=sqrt(n)+1;
for(int i=2;i<=k;i++)
if(is_prime[i])
for(int j=i;j<=n/i;j++)
is_prime[i*j]=false;
}
只用循环到n的平方根加1,又省时也很保险;
2.欧拉筛法(自己好像也没怎么懂,不就加了个prime[]栈来存吗?)
算了,直接上代码
void euler_sieve(int n)
{
totprimes=0;
memset(is_primes,1,sizeof(is_primes));
is_prime[1]=is_prime[0]=0;
for(int i=1;i<=n;i++)
{
if(is_prime[i])
primes[++totprimes]=i;
for(int j=1;i*primes[j]<=n&&j<=totprimes;j++)
{
is_primes[i*primes[j]]=0;
if(i%primes[j]==0) break;
}
}
}
好吧,其实有区别的;埃氏他们家的一个数可能被筛多次(如6被2筛了后又被3筛),在数据大的时后就很费时。而欧拉就机zhi了,只筛一次,把复杂度降到了线形;
这是如何实现的??
关键: if(i % primes[j]==0 ) break;
为什么呢?
证明网上是有的;这里就不赘述了;