【数论】素数筛法
素数筛法
一.前言#
素数是数论中颇为重要的一类数,我们往往需要对其进行判断。当我们需要寻找一个大范围内的所有素数时,如何筛选这些素数就显得非常重要了。本文中介绍了三种筛法:朴素判定,埃拉托色尼筛法,欧拉筛法。
二.朴素判定法#
当我们对一整个范围内的素数进行筛选时,一种朴素的方法很容易想到,那就是对其中每个素数进行判定,最简单的方法就是用试除法,对所有
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
scanf("%d",&n);
for (int i = 2; i <= n; ++i)
{
bool isPrime = true;
for (int j = 2; j * j <= i; ++j)
{
if (i%j==0)
{
isPrime = false;
break;
}
}
if(isPrime) printf("%d ",i);
}
return 0;
}
每个数
三.埃拉托色尼筛法(埃氏筛)#
众所周知,一个素数的倍数是素数,每个合数都能分解成若干个质因数,我们可以借此性质筛去每个素数的倍数,这样留下的必定是素数,因为比该素数小的所有可能因子的倍数已经被筛去。以下是实现代码。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e7;
int isNotPrime[N];
int main() {
int n;
scanf("%d", &n);
for (int i = 2; i <= n; ++i) {
if (!isNotPrime[i]) {
printf("%d ", i);
for (int j = i * i; j <= n; j += i) {
isNotPrime[j] = 1;
}
}
}
return 0;
}
这里有几个魔鬼细节。首先我们只对素数进行倍数筛去,因为一个合数必定有小于他的因子,那么他的倍数一定在小于他的因子时筛去,没有必要重复筛。另外内层循环
四.欧拉筛(线性筛)#
埃氏筛最大的缺点就是会对含有同一个因子的数重复筛去,这会浪费大量时间。欧拉筛,又称欧式筛,他运用和数能拆分成以他的最小素因数与另一个在筛选范围内的数的乘积形式,这一思想,扫描过范围内每一个数,在筛选的同时统计素数,每次筛去已经发现的素数中的素数与每扫描到的数的乘积,当发现扫描到的数与已发现的素数非互素,那么说明扫描到的数的所有倍数均含有这个素数因子,所以无需继续向后与其他素数做乘积,因为那个较小的素数的倍数必定会包含扫描数与后续素数的乘积(因为较小的素数是扫描数的因子)。这可以完美的避免重复筛选,因为他只会筛选到扫描到的数与其最小素因数的乘积,这不会导致某一个重复的因子在一次扫描中被重复利用,也不会导致某一个数被重复筛去,因为他会且仅会被他的最小因子所筛去,而不会被该因子的倍数所筛去。
#include<bits/stdc++.h>
using namespace std;
const int N = 1e7;
int isNotPrime[N];
int Prime[N], cnt;
int main() {
int n;
scanf("%d", &n);
for (int i = 2; i <= n; ++i) {
if (!isNotPrime[i]) {
printf("%d ", i);
Prime[++cnt] = i;
}
for (int j = 1; j <= cnt; ++j) {
if (Prime[j] * i > n) break;\\如果超过范围结束。
isNotPrime[Prime[j] * i] = 1;\\筛去当前扫描数与已发现的素数构成的合数,合数的最小数因子必定是Prime[j],因为素数是按序扫描的。
if (i % Prime[j] == 0) break;\\该素数是扫描数的因子,那么扫描数与后续素数的乘积必定含有该素因子,后续素数与扫描数的乘积的最小因子必定不是后续素数,而是该素数。
}
}
return 0;
}
欧拉筛对于
五.总结#
素数筛法可以在快速的时间内预处理一段范围内的素数,对于小范围需要高频的素数的素数判定的问题起到重要问题。而低频且大范围的素数判定问题,则需要高效的素性测试算法,我会单独出一篇文章,敬请期待。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)