赞
踩
C++判断素数:
方法1:朴素算法
可以先考虑素数的定义——只能被1和本身整除的数才是素数。
那我们可以先特判此数是否为0或1(因为它们既不是素数又不熟和数),然后循环判断此书能不能被2~本身-1之中的任何一个数整除,如果可以则是和数,否则是素数。
code
#include<iostream>
using namespace std;
bool isprime(int x){//判断是否为素数
if(x<2)return false;//不是素数
for(int i=2;i<x;i++)
if(x%i==0)//能被其他数整除
return false;
return true;
}
int main(){
int x;
cin>>x;
cout<<isprime(x)?"prime":"not prime";
return 0;
}
2.提升朴素算法
因为我们知道,一个数的因数是成对出现的,那么在一对因数里面肯定有一个数是小于等于
n
\sqrt{n}
n
的。那么我们的循环到sqrt(n)就行了
code:
#include<iostream>
using namespace std;
bool isprime(int x){//判断是否为素数
if(x<2)return false;//不是素数
for(int i=2;i*i<=x;i++)/*就这个改了*/
if(x%i==0)//能被其他数整除
return false;
return true;
}
int main(){
int x;
cin>>x;
cout<<isprime(x)?"prime":"not prime";
return 0;
}
我不会告诉你我是拷贝粘贴第一个版本的代码然后改的
3.进一步提升
因为我是蒟蒻,所以看了这篇文章后才知道知道了
O
(
N
)
O(\sqrt{N})
O(N
)的算法不是最快的算法。证明就不贴了(因为我太懒了)。这个算法的复杂度可以到
O
(
N
3
)
O(\frac{\sqrt{N}}{3})
O(3N
)
bool isprime(int n)
{
if(n==1) return false;
if(n==2||n==3) return true;
if(n%6!=1&&n%6!=5) return false;
for(register int i=5;i*i<=n;i+=6)
if(n%i==0||n%(i+2)==0) return false;
return true;
}
4.朴素筛法
想一下你要筛选从1~100里的所有素数,那么可以从2开始,每一次筛掉它的所有2倍以上的倍数(它们都不是素数了)。最后,没有被筛掉的就是素数了。
code:
#include<iostream> #include<cstring> using namespace std; const int MAXN=1e6; bool prime[MAXN+1]; void Screening(int n) { memset(prime,true,sizeof(prime); prime[0]=prime[1]=false; for(int i=2;i<=n;i++) { for(int j=2;j*i<=n;j++) { prime[i*j]=false; } } } int main() { int n; cin>>n; Screening(MAXN); cout<<prime[n]?"prime":"not a prime"; return 0; }
时间复杂度:筛选
O
(
N
log
N
)
O(N\log{N})
O(NlogN),判断
O
(
1
)
O(1)
O(1)
5.埃氏筛法(改进朴素筛法)
在上面的筛法中,还是有很多重复的,比如一个数是合数,在程序中也会把它的倍数筛掉,但是其实没有必要。还有,其实我们只用筛到
N
\sqrt{N}
N
.因为对于一个素数,它的第一个之前没有被筛选过的倍数是它的平方,那么在
N
\sqrt{N}
N
之后的素数不可以筛掉任何一个素数了,就没有必要筛了。
code:
#include<iostream> #include<cstring> using namespace std; const int MAXN=1e6; bool prime[MAXN+1]; void Screening(int n) { memset(prime,true,sizeof(prime); prime[0]=prime[1]=false; for(int i=2;i*i<=n;i++) { if(prime[i]) { for(int j=i;j*i<=n;j++) { prime[i*j]=false; } } } } int main() { int n; cin>>n; Screening(MAXN); cout<<prime[n]?"prime":"not a prime"; return 0; }
时间复杂度:筛选 O ( N log log N ) O(N\log{\log{N}}) O(NloglogN)(其实已经很接近 O ( N ) O(N) O(N)了),判断 O ( 1 ) O(1) O(1)
我是蒟蒻,您们人均AK IOI(((
其实还有很多我没有贴上来的,大家也可以搜一搜
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。