算法笔记之素数判定与素数表

何为素数:

素数又称为质数,是指除了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(),否则不会出结果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值