深入理解埃拉托色尼筛法与线性筛法
创作时间:
作者:
@小白创作中心
深入理解埃拉托色尼筛法与线性筛法
引用
CSDN
1.
https://m.blog.csdn.net/2202_75569688/article/details/142813349
在计算素数的过程中,有两种经典的筛法:埃拉托色尼筛法(简称埃筛)和线性筛法(简称线筛)。它们都是用于在给定的范围内找到所有素数的高效算法。本文将通过示例代码,详细对比这两种方法的原理、实现及其时间复杂度。
1. 埃拉托色尼筛法
原理概述
埃拉托色尼筛法的基本思想是通过不断标记合数来筛选出素数。具体来说,对于每一个素数 p,从 p*p 开始标记所有的倍数为非素数,因为更小的倍数已经在之前被标记过。
代码实现
以下是埃筛法的 C++ 实现:
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<int> isPrime(n + 1, 1); // 初始化所有数为素数
isPrime[0] = isPrime[1] = 0; // 0 和 1 不是素数
for (int i = 2; i * i <= n; i++) { // 从 2 开始到 sqrt(n)
if (isPrime[i]) { // 如果 i 是素数
for (int j = i * i; j <= n; j += i) { // 标记 i 的所有倍数为非素数
isPrime[j] = 0;
}
}
}
// 输出所有素数
for (int i = 0; i <= n; i++) {
if (isPrime[i]) {
cout << i << " ";
}
}
return 0;
}
解析
- 时间复杂度:埃拉托色尼筛法的时间复杂度为 O(nloglogn)。虽然对于每个素数 p,我们需要从 p*p开始标记所有倍数,但通过跳过非素数的倍数,算法仍然具有非常好的效率。
- 空间复杂度:我们使用了一个大小为 n+1的数组来存储每个数是否是素数,因此空间复杂度为 O(n)。
输出示例
对于 n=30,输出结果为:
2 3 5 7 11 13 17 19 23 29
优缺点
优点:
实现简单。
适用于中等范围的素数筛选。
缺点:
存在重复标记。例如,6 既是 2 的倍数也是 3 的倍数,因此会被多次标记。
时间复杂度虽然是 O(nloglogn),但不是最优的。
2. 线性筛法
原理概述
线性筛法通过优化标记过程,确保每个合数只会被它的最小素数因数标记一次,从而避免了重复标记。与埃拉托色尼筛法不同,线性筛法可以严格保持线性时间复杂度 O(n)。
代码实现
以下是线性筛法的 C++ 实现:
#include <bits/stdc++.h>
using namespace std;
int main(){
ios::sync_with_stdio(false);
cin.tie(NULL);
int n;
cin >> n;
vector<int> prime;
vector<int> isPrime(n + 1, 1); // 初始化所有数为素数
isPrime[0] = isPrime[1] = 0; // 0 和 1 不是素数
for (int i = 2; i <= n; i++) { // 从 2 遍历到 n
if (isPrime[i]) { // 如果 i 是素数
prime.push_back(i); // 将 i 加入素数列表
}
for (int j = 0; j < prime.size(); j++) {
int p = prime[j];
if (p * i > n) break; // 如果 p * i 超过了 n,停止标记
isPrime[p * i] = 0; // 标记 p * i 为非素数
if (i % p == 0) break; // 如果 i 能被 p 整除,停止标记
}
}
// 输出所有素数
for (int i = 0; i < prime.size(); i++) {
cout << prime[i] << " ";
}
return 0;
}
解析
- 时间复杂度:线性筛法的时间复杂度为 O(n),因为每个数 i 只会被其最小素数因数标记一次,避免了重复标记。
- 空间复杂度:与埃拉托色尼筛法类似,空间复杂度也是 O(n)。
输出示例
对于 n=30,输出结果为:
2 3 5 7 11 13 17 19 23 29
优缺点
优点:
时间复杂度为 O(n),更高效,特别是在处理大规模数据时效果显著。
每个合数只被最小素数标记一次,避免了不必要的重复操作。
缺点:
实现稍微复杂,需要维护素数列表并处理标记逻辑。
3. 对比分析
4. 总结
- 埃拉托色尼筛法是一个较为经典的素数筛选算法,适合中小规模的数据筛选,具有简单易懂的实现。
- 线性筛法在进一步优化了筛选过程,能够在线性时间内完成素数筛选,特别适合大规模数据的处理。
热门推荐
助消化,不可贪吃山楂
柔福帝姬結局是什麼?歷史上最悲慘帝姬的一生
一文详解视觉Transformer模型压缩和加速策略
金融行业的现状与就业前景
家门口来了骨科专家 患者乐享便捷服务
变频调速架线式工矿电机车自动断电的原理是什么?
全国人力资源和社会保障服务平台的技术支持电话是多少?
10月中国LPR下调25个基点,对A股有何影响?
美加发明新型固态电池,充电快不燃爆,续航或增两三倍!
中智伟业资讯 | 锂金属电池重大突破!能量密度高达500Wh/kg
股票的板块分类有哪些?不同板块的股票有什么特点?
概念股雪崩启示录:当击鼓传花变成资本绞肉机
二十四节气看吉林丨春分:冰雪消融春意浓 报春候鸟适时归
青海小天堂,天峻石林,99的人不知道的秘境,大西北必打卡景点。
青海地理位置与风土人情:多民族文化交融的高原省份
如何在激烈竞争中寻找蓝海市场?解析餐饮行业战略定位
《科学》:糖尿病的“隐形推手”找到了!阻断这个分子,恢复胰岛素敏感性
格律诗的基本知识和创作方法
新项目成立如何管理团队
剖析呼叫中心通话记录,解锁高效沟通与客户满意度提升密码
量子计算与佛法智慧:一场关于二元对立的跨时空对话
探索最新的商业模式:创新驱动未来
注意!钓到这种鱼赶紧放生,系国家二级保护鱼种,当心牢底坐穿
口服葡萄糖耐量试验(OGTT), 你做对了吗?
皮肤瘙痒症用什么药?专业医生详解用药方案
2024年电脑DIY装机入门指南:全面解析与实用建议
年轻人的焦虑与失眠,如何轻松调节?
轨道交通列车动力牵引策略研究
有什么适合提高 C/C++ 网络编程能力的开源项目推荐
柏林空袭中的塔防作战消耗有多大:第三帝国都被拖垮了半条命