当我们要求一段范围内的素数,并且数字范围比较广时,用普通的方法肯定会导致超时,这是我们不妨用埃氏筛法来解决;
用途:求一定范围内的素数
步骤:
(1)先把1删除(现今数学界1既不是质数也不是合数)
(2)读取队列中当前最小的数2,然后把2的倍数删去
(3)读取队列中当前最小的数3,然后把3的倍数删去
(4)读取队列中当前最小的数5,然后把5的倍数删去
(5)读取队列中当前最小的数7,然后把7的倍数删去
(6)如上所述直到需求的范围内所有的数均删除或读取
注:此处的队列并非数据结构队列,如需保留运算结果,处于存储空间的充分利用以及大量删除操作的实施,建议采用链表的数据结构
埃氏筛法程序:
求2到n之间的素数
int sieve(int n)//埃氏筛法
{
for(int i=2;i<=n;i++)
{
is_prime[i]=true;
}
is_prime[0]=is_prime[1]=false;//0和1都不是素数
for(i=2;i<=n;i++)
{
if(is_prime[i])
{
for(j=2;j*i<=m;j++)
is_prime[j*i]=false;
}
}
is_prime[i]中标记为1的i均为所求素数
实例:
求区间[n,m]之间的所有素数与个数
1=<n,m<=100000000;
#include<stdio.h>
long long is_prime[100000000];
int sieve(int n,int m)//埃氏筛法
{
long long i,j,count=0;
for(i=2;i<=m;i++)
{
is_prime[i]=1;
}
is_prime[0]=is_prime[1]=0;//0和1都不是素数
for(i=2;i<=m;i++)
{
if(is_prime[i])
{
if(i>=n&&i<=m)
{
printf("%d\n",i);//将区间[n,m]之间的素数输出*/
count++;
}
for(j=2;j*i<=m;j++)
is_prime[j*i]=0;
}
}
return count;
}
int main()
{
long long n,m;
scanf("%d%d",&n,&m);
printf("有%d个素数",sieve(n,m));//输出个数
return 0;
}
由于题目要求使用整型不够,所以这里用long long