素数

本文介绍了素数的概念,提供了判断一个数是否为素数的算法,并详细对比了暴力破解和筛法两种求解100以内素数的方法。通过具体代码示例,展示了不同算法的时间复杂度和实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

素数又称为质数,是指除了1和本身之外,不能被其他数整除的一类数。即对给定的正整数n,如果对任意的正整数a(1<a<n),都有n%a!=0成立,那么称n是素数;否则,如果存在a(1<a<n),使得n%a==0,那么称n为合数。应特别注意的是,1既不是素数,也不是合数

1.判断一个数是不是素数:

程序代码:

#include<cstdio> 
#include<cmath> 
bool isPrime(int n){
	if(n<=1) 	//特判,素数的范围大于1 
		return false;
	int sqr = (int)sqrt(1.0*n);//根号n 
	for(int i=2;i<=sqr;i++){ 	//遍历2~根号n 
		if(n%i==0) 
			return false;		//n是i的倍数,n不是素数 
	}
	return true;	//否则n是素数 
}
int main(){
	int a;
	while(scanf("%d",&a)!=EOF)
		printf("%d\n",isPrime(a));
	return 0;
}

运行结果:

说明:

在上述代码中,sqrt的作用为一个浮点数取整,需要添加math.h头文件。由于sqrt的参数要求是浮点数,因此在n前面乘以1.0来使其成为浮点型。

时间复杂度:O(sqrt(n))

 

 

2.求解100以内的素数:

(1)暴力破解:

程序代码:

#include<cstdio> 
#include<cmath> 
bool isPrime(int n){
	if(n<=1) 	//特判,素数的范围大于1 
		return false;
	int sqr = (int)sqrt(1.0*n);//根号n 
	for(int i=2;i<=sqr;i++){ 	//遍历2~根号n 
		if(n%i==0) 
			return false;		//n是i的倍数,n不是素数 
	}
	return true;	//否则n是素数 
}
int main(){
	int a;
	for(int i=2;i<=100;i++){
		if(isPrime(i))
			printf("%d\n",i);
	}
	return 0;
}

运行结果:

时间复杂度:O(n*n^(1/2))

 

(2)“筛法”

“筛法”是众多筛法中最简单且容易理解的一种,即 Eratosthenes筛法。素数筛法的关键就在一个“筛”字。算法从小到大枚举所有数,对每一个素数,筛去它的所有倍数,剩下的就都是素数了。

可能有读者问,一开始并不知道哪些数是素数,所以我们先要事先确定素数2。当从小到大到达某数a时,如果a没有被前面步骤的数筛去,那么a一定是素数。这是因为,如果a不是素数,那么a一定有小于a的素因子,这样在之前的步骤中a一定会被筛掉,所以,如果当枚举到a时还没有被筛掉,那么a一定是素数。

至于“筛”这个动作的实現,可以使用一个bool型数组p来标记,如果a被筛掉,那么p[a]为true;否则,p[a]为 false。在程序开始时可以初始化p数组全为 false。

程序代码:

#include<cstdio> 
const int maxn = 101;		//表长 
int prime[maxn],pNum=0;		//prime数组存放所有素数,pNum为素数个数 
bool p[maxn] = {0};		//如果i为素数,则p[i]为false;否则p[i]为true 
void Find_Prime() {
	for(int i=2;i<maxn;i++) { //从2开始,i<maxn结束,注意i不能等于maxn 
		if(p[i]==false){	//如果i是素数 
			prime[pNum++]=i;	//把素数i存到prime数组中 
			for(int j=i;j<maxn;j+=i){		//筛去所有i的倍数,循环条j不能等于maxn  
				p[j]=true;
			}
		}
	}
}
int main(){
	Find_Prime();
	for(int i=0;i<pNum;i++){
		printf("%d\n",prime[i]);
	}
	return 0;
}

运行结果:

时间复杂度:O(nloglogn),不必证明

练习题:数素数

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值