埃氏筛和线性筛的比较

在解决涉及素数筛选的问题时,埃氏筛在处理大数据时容易超时。线性筛通过优化避免了多余计算,其时间复杂度为O(N),相比埃氏筛的O(NloglogN)在大数据量下优势明显。对于1e7的数据,线性筛计算次数仅为埃氏筛的约1/2.7,更适合处理大规模问题。建议在算法学习中优先考虑使用线性筛。

这段时间在洛谷上面写题目的时候,发现对于莫比乌斯反演这种题目,以及一些其他的求素数的题目,假如要进行筛素数的时候,用埃氏筛一般都会被T,所以我想对这两种算法进行一个性能的对比。

首先,我们来看到埃氏筛,先给出代码:

//筛出1-n之间的素数
bool vis[1e7]={
   
   false};  //初始化全为false
void Eratosthenes(int n){
   
   
    for(int i=2;i<=n;i++){
   
   
        if(vis[i]==false){
   
     //发现这个是素数
   
### 埃拉托色尼筛法 vs 线性筛法:原理与时间复杂度对比 埃拉托色尼筛法(Eratosthenes Sieve)是一种经典的筛选素数的方法,其核心思想是从2开始,将每个找到的素数的倍数标记为非素数。这种方法简单易懂,但存在重复标记的问题[^1]。例如,当筛选到6时,它会被23分别标记一次。因此,在较大的范围内,这种重复操作会显著影响性能[^2]。 线性筛法(Linear Sieve),也被称为欧拉筛法,通过确保每个合数只被其最小质因数筛除一次来避免重复标记。该方法使用一个数组记录每个数是否已被筛过,并在遍历过程中维护一个质数列表,从而实现高效的筛选过程[^3]。 #### 时间复杂度分析 - **埃拉托色尼筛法**的时间复杂度约为 $O(n \log \log n)$。这是因为在每一轮中,算法会对当前素数的所有倍数进行标记,导致一些数被多次处理。 - **线性筛法**的时间复杂度为 $O(n)$,因为它保证了每个数仅被处理一次,这使得它在大规模数据下表现更优[^3]。 #### 示例代码对比 ##### 埃拉托色尼筛法 (C语言) ```c #include <stdio.h> #include <stdbool.h> void sieve(int n) { bool is_prime[n+1]; for (int i = 0; i <= n; i++) { is_prime[i] = true; } is_prime[0] = is_prime[1] = false; for (int p = 2; p * p <= n; p++) { if (is_prime[p]) { for (int i = p*p; i <= n; i += p) { is_prime[i] = false; } } } // 输出所有素数 for (int i = 2; i <= n; i++) { if (is_prime[i]) { printf("%d ", i); } } } int main() { int n = 30; sieve(n); return 0; } ``` ##### 线性筛法 (C语言) ```c #include <stdio.h> #define MAXN 10000 int prime[MAXN], ct = 0; // 存储找到的质数 int v[MAXN]; // 记录0~MAXN是否为质数 void fprime(int b) { // 线性筛法找质数 for (int i = 2; i <= b; i++) { if (v[i] == 0) { // v[i]没被筛过,v[i]为质数 prime[++ct] = i; } for (int j = 1; j <= ct && i * prime[j] <= b; j++) { v[i * prime[j]] = 1; // 标记不为质数的数 if (i % prime[j] == 0) break; // 当遇到最小的质数是i的因数时,break } } } int main() { int n = 30; fprime(n); // 输出所有素数 for (int i = 1; i <= ct; i++) { printf("%d ", prime[i]); } return 0; } ``` ###
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值