素数判断及筛法

素数简介

素数(prime number)又称质数,有无限个。
素数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。

接下来介绍几种判断素数的方法:

问法1:给定一个数n,判断n是不是素数

一、暴力枚举

枚举2~n-1分别当做除数,判断是否能整除,如果某个数能把n整除,那么就说明n不是素数,如果所有都不能整除,那么n就是素数。
注:n=1或n=2时需要特判

详见代码:

bool work(int n)
{
	if(n==1)return false;
	if(n==2)return true;
	for(int i=2;i<=n-1;i++)
	{
		if(n%i==0)return false;
	}
	return true;
}

然而这样会很慢…

二、优化过的暴力算法

由于n至少会有一个约数在sqrt(n)中,所以我们可以直接枚举从2~sqrt(n),这样便会快不少。

详见代码:

bool work(int n)
{
	if(n==1)return false;
	if(n==2)return true;
	for(int i=2;i*i<=n;i++)//这里也可以写成i<=sqrt(n)
	{
		if(n%i==0)return false;
	}
	return true;
}

以上所说的算法只是用来判断单个素数的,但是若是要求1~n之间的素数该怎么办呢?

还是暴力?
不!
要用到一个名叫“筛法”的东东

三、埃氏筛法

由于我们知道,2的任何倍数都不可能是素数,3的任何倍数不可能是素数,5的任何倍数不可能是素数…
所以我们可以把素数的倍数全部筛掉。
详见代码:

/*
vis用来判断有没有被筛掉,
prime用来存储素数
cnt代表素数总数
*/
for(int i=2;i<=n;i++)
{
	if(vis[i]==1)continue;
	prime[++cnt]=i;
	for(int j=1;j*i<=n;j++)//筛掉素数的所有倍数
	{
		vis[j]=1;
	}
}

但是以12为例
12是2的倍数,被筛
12是3的倍数,被筛++
所以事实证明会有一些数被筛好多次
那要怎么做到每个数只筛一次的线性复杂度呢?

四、线性筛

线性筛,又称欧拉筛
欧拉筛法的基本思想 :在埃氏筛法的基础上,让每个合数只被它的最小质因子筛选一次,以达到不重复的目的。

/*
vis用来判断有没有被筛掉,
prime用来存储素数
cnt代表素数总数
*/
for(int i=2;i<=n;i++)
{
	if(!vis[i])prime[++cnt]=i;
	for(int j=1;j<=cnt&&i*prime[j]<=n;j++)
	{
		vis[i*prime[j]]=1;
		if(i%prime[j]==0)break;
	}
}

以上就是素数判断及筛法的总结,谢谢观看

参考文献资料:
https://www.baidu.com
https://blog.csdn.net/qq_39763472/article/details/82428602

最后打个小广告:
hulean.tk

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值