筛素数方法(三)——除余法

当你要筛选出2~n之间的质数时,除了线性筛MR素数判断等方法以外,还有一种叫做除余法的算法。

 

 除余法的优点           

 时间复杂度:O((n√n)/3)   

 空间复杂度:较低              

 

筛出2~n之间的素数比较暴力的方法,自然就是暴力枚举加上O(√n)判断,代码如下:

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> Prime;
bool Is_prime(int x)//O(√n)判断 
{
	if(x<2) return false;
	for(int i=0;i<Prime.size()&&Prime[i]*Prime[i]<=x;i++) if(!(x%Prime[i])) return false;
	return true;
}
int main()
{
	scanf("%d",&n);
	for(int i=2;i<=n;i++) if(Is_prime(i)) Prime.push_back(i);//暴力枚举 
	for(int i=0;i<Prime.size();i++) printf("%d ",Prime[i]);
	return 0;
}

其中的Is_prime()函数枚举了2~√n之间的全部质数来判断n是否为质数,这也是一个比较快速的判断是否为质数的函数。

 

这篇文章要讲的除余法,其实优化的并不是判断是否为质数的函数,而是调用函数的次数。

首先,我们要证明一点:任意一个大于3的质数p都可以用6n+1或6n+5的形式来表示(n为自然数)。

证明见下:

对于任意一个自然数,都可以表示为6n或6n+1或6n+2或6n+3或6n+4或6n+5(n为自然数),所以我们要进行分类讨论。

当p=6n时,很显然是一个合数

当p=6n+1时,无法确定其是否为合数

当p=6n+2时,可以表示为2(3n+1),很显然是一个合数

当p=6n+3时,可以表示为3(2n+1),很显然是一个合数

当p=6n+4时,可以表示为2(3n+2),很显然是一个合数

当p=6n+5时,无法确定其是否为合数

综上所述,若p为大于3的质数,则p必定可以用用6n+1或6n+5的形式来表示(n为自然数)

证明了这个,就可以直接推导出除余法了:

建立一个指针i,一开始指向5,随后依次增加2,4,2,4......直至i>n。对于每一个i,用其向素数集合中每一个小于√i的数取模,若能被整除,则i为合数,若每一个数都不能整除,则将i加入素数集合中。

具体实现过程中记得初始化:若n>=2,则将2加入素数集合;若n>=3,则将3加入素数集合。

代码如下:

#include<bits/stdc++.h>
using namespace std;
int n;
vector<int> Prime;
bool Is_prime(int x)//O(√n)判断 
{
	if(x<2) return false;
	for(int i=0;i<Prime.size()&&Prime[i]*Prime[i]<=x;i++) if(!(x%Prime[i])) return false;
	return true;
}
int main()
{
	scanf("%d",&n);
	if(n>=2) Prime.push_back(2);
	if(n>=3) Prime.push_back(3);
	int i=5;
	while(i<=n)//枚举每一个i 
	{
		if(Is_prime(i)) Prime.push_back(i);
		if((i+=2)>n) break;//将i增加2 
		if(Is_prime(i)) Prime.push_back(i);
		i+=4;//将i增加4 
	}
	for(int i=0;i<Prime.size();i++) printf("%d ",Prime[i]);
	return 0;
}

 

 

 

 

 

注:如果您通过此文学会了除余法,请您点个赞再离开。当然,也欢迎在讨论区指出此文的不足处,作者会及时对此文加以修正
版权声明:转载请注明地址

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值