线性筛法求素数

和朴素的筛法求素数不同,线性筛法可以省去许多重复的删除

 

例如12:它可以被2,6;3,4筛掉,被筛了2次;

所以新的算法是在处理数i时,枚举i之前的所有质数并用i*质数进行删除,直到第一个质数k能整除i就在这之后停止,因为接下来的所有质数所产生的需要被筛的数num=p*i都可以在后面的枚举到(i/k*p)时被筛掉:(i/k*p)*k(显然可以保证在k之前没有一个数能整除(i/k*p)),所以这样就能保证所有合数只被筛掉了一遍

 1 void init(int k)
 2 {
 3     memset(bl,1,sizeof(bl));
 4     bl[1]=0;
 5     for(int i=2;i<=k;i++)
 6     {
 7         if(bl[i]) prime[++tot]=i;
 8         for(int j=1;j<=tot;j++)
 9         {
10             if(i*prime[j]>k) break;
11             bl[i*prime[j]]=0;
12             if(i%prime[j]==0) break;
13         }
14     }
15 }
View Code

 

转载于:https://www.cnblogs.com/Forever-666/p/10660949.html

线性筛法(也称为欧拉筛法)是一种高效的素数筛选算法,其时间复杂度为 $O(n)$,能够在线性时间内筛选出 $1$ 到 $n$ 之间的所有素数。该方法的核心思想是通过遍历每个数,并将合数仅被标记一次,从而避免重复筛除,提高效率。 以下是一个使用 C++ 实现线性筛法的示例代码: ```cpp #include <iostream> #include <vector> std::vector<int> linear_sieve(int n) { std::vector<bool> is_prime(n + 1, true); // 用于标记每个数是否为素数 std::vector<int> primes; // 存储素数列表 for (int i = 2; i <= n; ++i) { if (is_prime[i]) { primes.push_back(i); // 如果i是素数,加入素数列表 } // 遍历当前已找到的素数列表 for (size_t j = 0; j < primes.size() && i * primes[j] <= n; ++j) { is_prime[i * primes[j]] = false; // 标记该合数 if (i % primes[j] == 0) { break; // 确保每个合数只被其最小的质因数筛除一次 } } } return primes; // 返回n以内的所有素数 } int main() { int n; std::cout << "请输入一个正整数n:"; std::cin >> n; std::vector<int> primes = linear_sieve(n); std::cout << "1到" << n << "之间的素数有:" << std::endl; for (int prime : primes) { std::cout << prime << " "; } std::cout << std::endl; return 0; } ``` ### 代码说明: 1. **标记数组 `is_prime`**:用于记录每个数是否为素数,初始时设为 `true`。 2. **素数列表 `primes`**:存储筛选出的素数。 3. **外层循环**:从 $2$ 到 $n$ 遍历每个数 $i$。 4. **内层循环**:对于每个素数 $p$,标记 $i \times p$ 为合数;当 $i$ 能被当前素数整除时,停止内层循环以避免重复标记。 5. **输出结果**:将筛选出的素数打印出来。 ### 算法特点: - **高效性**:每个合数只会被其最小的质因数筛除一次,因此时间复杂度为 $O(n)$。 - **空间复杂度**:需要一个大小为 $n+1$ 的布尔数组来标记素数,因此空间复杂度为 $O(n)$。 通过该算法,可以在较短时间内处理大规模的素数筛选问题,适用于对性能要较高的场景。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值