法一:
int IsPrime(int n)
{
int i;
if(n<2||(n!=2&&n%2==0))
return 0;
else
{
for(i=3;i*i<=n;i+=2)
{
if(n%i==0)
return 0;
}
return 1;
}
}
法二:(埃氏筛)
补充:算术基本定理可表述为:任何一个大于 1 的自然数 N,如果 N 不为**质数**,那么 N 可以唯一分解成有限个质数的乘积
#define maxn 20010
int vis[maxn];//vis用来判断数字是否访问过
int prime[maxn];//prime用来存储筛选出来的素数
int sieve(int n)
{
int i,j,k;
k=0;
memset(vis,0,sizeof(int)*maxn);
vis[0]=vis[1]=1;
for(i=2;i<=n;i++)
{
if(vis[i]==0)
{
prime[k++]=i;
for(j=2;i*j<=n;j++)
vis[i*j]=1;//只对素数进行倍增筛选,其他基本不变
}
}
return k;
}
int sieve(int n)
{
if(n<2)
return 0;
int i,j,k;
k=0;
memset(vis,0,sizeof(int)*maxn);
vis[0]=vis[1]=1;
vis[2]=0;
prime[k++]=2;
for(i=3;i<=n;i+=2)
{
vis[i+1]=1;//把偶数的标记补上
if(vis[i]==0)
{
prime[k++]=i;
for(j=i;i*j<=n;j++)
vis[i*j]=1;
}
}
return k;
}
int Eratosthenes_sieve(int n)
{
if(n<2)
return 0;
int i,j,k;
k=0;
memset(vis,0,sizeof(int)*maxn);
vis[0]=vis[1]=1;
vis[2]=0;
for(i=4;i<=n;i+=2)//这里把偶数全部标记为1,非素数
vis[i]=1;
for(i=3;i*i<=n;i+=2)//这里只是把 i<=n 改为 i*i<=n
{
if(vis[i]==0)//对素数进行倍增
{
for(j=i;i*j<=n;j++)//这里把j=2改为j=i
vis[i*j]=1;
}
}
//上面的循环,只循环到sqrt(n),因此要存储范围内的素数,需要重头遍历一遍
prime[k++]=2;
for(i=3;i<=n;i+=2)//只遍历奇数
{
if(vis[i]==0)
prime[k++]=i;
}
return k;//返回素数的个数
}
法三:(欧拉筛)
int Euler_sieve(int n)
{
int i,j,k;
k=0;
memset(vis,0,sizeof(int)*maxn);
for(i=2;i<=n;i++)
{
if(vis[i]==0)
prime[k++]=i;
for(j=0;j<k;j++)//进行倍增,用i去乘以i之前(包括i)的素数
{
if(i*prime[j]>n)//倍增结果超出范围,退出
break;
vis[ i*prime[j] ]=1;//将倍增结果进行标记
if(i%prime[j]==0)//i是前面某个素数的倍数时,也需要退出
break;
}
}
return k;//返回素数的个数
}