素数判定与素数表
何为素数:
素数又称为质数,是指除了1和本身之外,不能被其他数整除的数。对给定的正整数n,如果对任意的正整数a(1<a<n),都有n%a!=0成立,就称n是素数;否则如果存在a(1<a<n),使得n%a==0,就称n为合数。1既不是素数,也不是合数。
素数判定:
n未接近到int类型范围上界:
当n未接近到int类型范围上界时,素数判定代码如下:
bool isprime(int n){
if(n<=1)
return false;
for(int i=2;i*i<=n;i++){
if(n%i==0)
return false;
}
return true;
}
当n接近int类型范围上界时会导致i*i溢出,解决方法:将i定义为long long型或使用sqrt()判定,判定n能否被2, 3,…, Lsqrt(n)」中的一个整除(其中 Lx」表示对x向下取整),即可判定n是否为素数。该算法的复杂度为O(sqrt(n))。
若n接近到int类型范围上界:
bool isprime(int n){
if(n<=1)
return false;
int k=(int)sqrt(1.0*n);
for(int i=2;i<=k;i++){
if(n%i==0)
return false;
}
return true;
}
素数表的获取:
1~n枚举(非筛法):
从1~n枚举,判断每个数是否是素数,如果是素数就加入素数表。枚举部分的复杂度是O(n),判断素数的复杂度是0(√n),总复杂度是0(n√n)。这个复杂度要求n不能超过10^5。
1~n枚举(非筛法)代码实现:
#define maxn 101 //表长
int prime[maxn],ans=0; //prime存放素数,ans为素数个数
bool p[maxn]={0};
void findprime(){
for(int i=1;i<maxn;i++){
if(isprime(i)==true){
prime[ans++]=i; // 若为素数则把i存入prime数组
p[i]=true;
}
}
}
素数表的获取(1~n枚举非筛法)应用举栗🌰:
求解输出100以内的所有素数。
C++代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int prime[101],ans=0;
bool p[101]={0};
bool isprime(int n){ //素数判定
if(n<=1)
return false;
int k=(int)sqrt(1.0*n);
for(int i=2;i<=k;i++){
if(n%i==0)
return false;
}
return true;
}
void findprime(){ //求素数表
for(int i=1;i<101;i++){
if(isprime(i)==true){
prime[ans++]=i;
p[i]=true;
}
}
}
int main(){
findprime();
for(int i=0;i<ans;i++){
cout<<prime[i]<<" ";
}
return 0;
}
素数筛法:
当n超过10^5时,此算法也就不在适用。因此迎来了素数筛法的高光时刻!!!时间复杂度为O(nloglogn)。从小到大枚举所有数,对每一个素数, 筛去它的所有倍数,剩下的就都是素数了。从小到大到达某个数a时,如果a没有被前面步骤的数筛去,则a一定是素数。因为如果a不是素数,则a一定有小于a的素因子,这样在之前的步骤筛选中a一定会被筛掉,因此如果当枚举到a时还没有被筛掉,则a是素数。“筛”的实现,可以借助一个个bool型数组p来进行标记,如果a被筛掉,那么p[a]为true;否则p[a]为 false。
素数筛法代码实现:
#define maxn 101 //表长
int prime[maxn],ans=0; //prime存放素数,ans为素数个数
bool p[maxn]={0};
void findprime(){
for(int i=2;i<maxn;i++){
if(p[i]==false){ //i为素数
prime[ans++]=i; //把i存入prime数组
for(int j=i+i;j<maxn;j+=i){ //筛掉所有i的倍数
p[j]=true;
}
}
}
}
素数表的获取(素数筛法)应用举栗🌰:
求解输出100以内的所有素数。
C++代码如下:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int prime[101],ans=0;
bool p[101]={0};
void findprime(){ //素数筛法
for(int i=2;i<101;i++){
if(p[i]==false){
prime[ans++]=i;
for(int j=i+i;j<101;j+=i){
p[j]=true;
}
}
}
}
int main(){
findprime();
for(int i=0;i<ans;i++){
cout<<prime[i]<<" ";
}
return 0;
}
注意事项:
①1不是素数。
②素数表长至少要比n大1。
③main函数中要记得调用findprime(),否则不会出结果。