素数筛
素数的定义
质数又称素数。一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。2是最小的素数。
朴素的算法
对于一个数n来说,枚举从2-sqrt(t)的数。(因数是成对出现的,若a*b=n,那么必然有一个因数<=sqrt(n),一个因数>= ,所以只要枚举到根号,就能判断)如果能整除n,说明n除了1和它自身外还有其他因数,为合数。
bool is_prime(int n)
{
if (n <= 1)return false;
for (int i = 2; i <= sqrt(n); i++)
{
if (n % i == 0)
return false;
}
当然这个for循环你也可以这么写,代表的意思是一样的
for (int i=2;i*i<=n;i++)
也可以这样去写,上面的写法有可能i*i后爆范围
for (int i=2;i<=n/i;i++)
return true;
}
小细节的理解:<=中的=不要忘记。可以举例4.
sqrt返回的是double 类型,i的int类型会转化double进行比较。
时间复杂度:判断一个数是sqrt(n)
判断1-n区间内是n*srqt(n)
素数筛的基本思想
思考方向的转变:
上面的朴素算法,我们是尝试把数字拆分为因子相乘的形式,对范围区间内的数字进行判断时,则需要对每个数字都进行拆分,那么我们是否可以使用另外一种方式呢?
这里我们选择另外一种方式:反向构造。
我们事先不知道一个数是否为素数,但是我们可以创造出合数(非素数)。
数字可以划分为素数和合数两大类,那么当我们把某一范围内的合数都标记出来,则剩下的数字就是素数。
如何构造合数呢?在大于1的数字中任取两个数字a,b相乘即可,这样得到的结果c必然有1,a,b,c四个因子(当a=b时为三个因子)那么c必然是合数
(这一部分转载传送门 )原文链接:https://blog.youkuaiyun.com/Yuki_fx/article/details/115103663
基本思想
算术基本定理:任一大于1的自然数,要么本身是质数,要么可以分解为几个质数之积,且这种分解是唯一的。
既然每一个合数必然能够分解成多个素数的乘积,那么在搜索到一个数为素数的时候,我们就把他的倍数标记为合数。(这里是倍增的思想