先代码奉上:
试除法
#include<iostream>
#include<cmath>
using namespace std;
bool isprime(int n)
{
if(n<=1) return false;
for(int i=2;i<=n/i;i++)
{
if(n%i==0) return false ;
else return true;
}
}
int main()
{
int n;
cin>>n;
cout<<isprime(n)<<endl;
}
1.判断用 bool类型
2.为了节约时间
1.i<=n;
2.i<=sqrt(n);//记得用上#include <cmath>
3.i<=n/i;//防止溢出
埃式筛
#include <iostream>
using namespace std;
const int N=1e5;
int n;
bool status[N];
int primes[N];
int num=0;
bool get_primes(int n)
{
for(int i=2;i<=n;i++)
{
if(!status[i]){primes[num]=i;
num++;
}
for(int j=i*2;j<=n;j=j+i)
{
status[j]=1; //时间复杂度约为o(n*log2n)
}
}
}
int main()
{
cin>>n;
get_primes(n);
for(int i=0;i<num;i++)
{
cout<<primes[i]<<" ";
}
return 0;
}
总结归纳:埃式筛运用 是不是2的倍数,3的倍数,4的倍数来筛。。。以此类推。
首先定义一个状态数组(判断它是否为素数,bool类型,建议0为素数,1为合数),定义一个用来装素数的数组(int 类型即可),初始一个num=0 用来判断素数个数,一个整数n。之后写一个bool 类型的函数(用来获取素数数组和素数个数),从2开始即可(n<=1 尚且归为不在考虑范围之类),此时建议0为素数,1为合数起作用了,定义在函数外的数组初始化为0,所以没有判断的数即为素数。因此若直接从i等于2开始,int j=i*2;j<=n;j+=i,的数为大于等于4的合数。把它们改变一下状态即可。最后记得运用函数前,必须先调用该函数,可以看到get_primes(int n)函数并没有输出的值,而是把素数数组和素数个数分别存入了数组和num 中。
欧拉筛
#include <iostream>
using namespace std;
const int N=1e5;
int n;
bool status[N];
int primes[N];
int num=0;
bool get_primes(int n)
{
for(int i=2;i<=n;i++)
{
if(!status[i]){primes[num]=i;
num++;
}
for(int j=0;primes[j]<=n/i;j++)
{ //时间复杂度为0(n)
status[primes[j]*i]=1;
if(i%primes[j]==0) break;
}
}
}
int main()
{
cin>>n;
get_primes(n);
for(int i=0;i<num;i++)
{
cout<<primes[i]<<" ";
}
return 0;
}
#include <iostream>
using namespace std;
const int N=1e5;
int n;
bool status[N];
int primes[N];
int num=0;
bool get_primes(int n)
{
for(int i=2;i<=n;i++)
{
if(!status[i]){primes[num]=i;
num++;
}
for(int j=0;primes[j]<=n/i;j++)
{ //时间复杂度为0(n)
status[primes[j]*i]=1;
if(i%primes[j]==0) break;
}
}
}
int main()
{
cin>>n;
get_primes(n);
for(int i=0;i<num;i++)
{
cout<<primes[i]<<" ";
}
return 0;
}
总结归纳:原理:只用最小质因子来筛
可以发现 欧啦筛与埃式筛只有两行代码的区别,但是欧啦筛却比埃式筛快几个数量级。
注意;用的是最小质因子来筛,为了是最小,我们从0开始枚举,为了是素数,我们从素数数组中挑选它的倍数,注意素数*i=合数(我们要筛的数)。primes[j]<=n/i,其实就是如此。为了不和埃式筛一样重复,我们(i%primes[j]==0) break;跳出即可。