筛法求素数
筛法
具体做法是:先把N个自然数按次序排列起来。1不是素数,也不是合数,要划去。
第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。
这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。
又称:“埃拉托斯特尼筛”,简称“筛法”。
实现:
-
先将1去掉。
-
除去2的倍数
-
除去3的倍数
。。。。。。
除去的方法就是,从 i i i 的第二倍开始,每次 $ j+=i$ ,遍历它的倍数。
注意点:
- 如果 N N N是合数,则它有一个因子 d d d满足$ 1<d≤\sqrt{N}$ ,所以 i i i 的范围小于 N \sqrt{N} N。
初始化:(打算数组从1开始记)
void INIT()
{
memset(is_prime,1,sizeof(is_prime));
is_prime[0]=0; is_prime[1]=0;
}
只是要素数表:
void get_prime()
{
INIT();
for(int i=2;i<=(int)sqrt(MAXN);++i) //有时要开long
{
if(is_prime[i])
for(int j=i*2;j<=MAXN;j+=i)
is_prime[j]=0;
}
return ;
}
求得所有的素数:
int get_prime()
{
INIT();int tot=0;//tot写在这,刚好就作返回值回去
for(int i=2;i<=(int)sqrt(MAXN);++i)
{
if(is_prime[i])
{
prime[++tot] = i;
for(int j=i*2;j<=MAXN;j+=i)
is_prime[j] = 0;
}
}
return tot;
}
int main()
{
int n=get_prime();
for(int i=1;i<n;++i)
printf("%d\n",prime[i]);
return 0;
}