线性的质数判断——欧拉筛法

质数本身这个概念很简单,要找因子只有1和它本身的数,最简单的求法就是1到根号n遍历判断因子,单次判断要根号n;

如果要遍历1到n的话,复杂度是O(n3/2),处理小规模的数据没问题,但是大规模就会比较慢。

当然如果只要判断一个数,那直接用这个就很快;

蒋委员长说过一句名言:以空间换时间,这个决策在历史上被人臭骂,但是在计算机领域确实是个很不错的思想,因为大部分情况时间复杂度比空间要宝贵的多。

那么这里就有一种以空间换时间的方法,叫筛法;

筛法的基础思想就是当我们遍历从2开始的数时,每遍历一个,把它的倍数全部标记了,后面就不用重复判断了,因为被标记就意味着是1和其本身以外的数的倍数,那就不符合质数的定义了。这个其实就是Eratosthenes筛法,最朴素的筛法,要介绍欧拉筛法,需要先理解这个朴素的筛法。

Eratosthenes筛法

筛法是Eratosthenes(下称埃氏),一个生活在公元前300年左右的希腊数学家发明的,时间复杂度为O(nloglogn),但是需要先建立大数组去存下范围内所有的数,所以空间复杂度高于直接用根号法遍历。

具体做法是,假设范围是N,先建立一个数组,开到比N大一点,下标就表示2到N的每一个数,下标对应的值表示这个下标是否被标记,也就是它是否是合数,全部初始化为1。然后i从2开始遍历,标记i所有的倍数的值为0,比如2的倍数4,6,8……,3的倍数6,9……,被标记的数因为有了非1和本身的因子所以是合数。

当遍历到一个数没有被标记时,说明比它小的数中没有它的因数,那么它就是质数了(当然它的倍数还是要标记的),可以记入一个专门存放质数的数组里,这样就可以建立一个从1到N的质数查询表。

我在网上找到了一张非常直观的动图可以来展示这个过程
在这里插入图片描述
这个思路相对简单,在具体做法那一段已经基本上按照写代码的思路讲解了一遍了,那么现在就直接,上代码!

#include<stdio.h>
#include<memory.h>
 
const int N = 100;//看题目范围改就行 
bool isPrime[N];//标记数组,类型是bool或者int都行,只存01值标记用 
int primes[N];//存质数的数组 
//当然,当数据太大导致普通数组存不下的时候,可以采用stl里的vector来存
int cnt;
 
void judgePri()
{
   
	memset(isPrime, 1, sizeof<
  • 6
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值