线性筛法(一)--素数筛法(二)
2017-05-31 17:20
295 查看
换一种筛子
但是这种方法还是有问题:比如筛30时,在 i=2 的时候, k = 2 * 15 筛了一次;在 i=5, k = 5 * 6 的时候又筛了一次。
今天我们换一种思路,并添加一个优化,从而解决这个问题,还是求1-n的素数。
核心思想:所有的合数可以表示为两个或多个素数的积。(实际上也相当于合数为素数乘一个比它小的合数-。-)
实现:我们遍历每个数,把它与之前找到的素数相乘,把相乘的结果标记为合数。
——实际上是把上一篇的“某个素数乘以每个数”改为了“每个数乘以某个素数”,但是由于我们做了一点优化,使前面提到的重复情况去除,所以算法得到了改进。
1,初始化(a数组标记,queue数组存素数与素数乘积)
2,我们先找到2,存入数组queue;
3,进行素数相乘 2x2,标记 4;
4,找到3,并对3进行操作。。。;
5,找到4,但不放入queue,并对 4 处理
6,如此操作。。。
我们来看看程序:
上一篇:线性筛法(一)–素数筛法(一)
换一种筛子
上一篇我们讲到用素数的倍数一定不是素数这一个方法来构建筛子。不清楚的童鞋可以再看看。但是这种方法还是有问题:比如筛30时,在 i=2 的时候, k = 2 * 15 筛了一次;在 i=5, k = 5 * 6 的时候又筛了一次。
今天我们换一种思路,并添加一个优化,从而解决这个问题,还是求1-n的素数。
核心思想:所有的合数可以表示为两个或多个素数的积。(实际上也相当于合数为素数乘一个比它小的合数-。-)
实现:我们遍历每个数,把它与之前找到的素数相乘,把相乘的结果标记为合数。
——实际上是把上一篇的“某个素数乘以每个数”改为了“每个数乘以某个素数”,但是由于我们做了一点优化,使前面提到的重复情况去除,所以算法得到了改进。
1,初始化(a数组标记,queue数组存素数与素数乘积)
a | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
queue | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
a | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 0 | 0 | 0 | 4000 0 | 0 | 0 | 0 | 0 |
queue | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
a | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
queue | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
a | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
- | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
queue | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 |
a | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
- | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 0 | 1 |
queue | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
---|---|---|---|---|---|---|---|---|
- | 2 | 3 | 0 | 0 | 0 | 0 | 0 | 0 |
我们来看看程序:
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; const int N = 100001; int main() { int n; int a ; int queue ; while(scanf("%d",&n) == 1) { memset(a,0,sizeof(a)); memset(queue,0,sizeof(queue)); int tail = 0; for(int i = 2; i < n; i++) { if(a[i] == 0) queue[tail++] = i; for(int j = 0; j < tail && i * queue[j] < N; j++) { a[i * queue[j]] = 1; if(!(i % queue[j]))//这是一个优化,去除15*2,6*5的重复 break; } } printf("2"); for(int i = 3; i < n; i++) { if(a[i] == 0) printf(" %d",a[i]); } } return 0; }
上一篇:线性筛法(一)–素数筛法(一)
相关文章推荐
- 大范围素数筛法性能测试(2^64)
- poj 2689 Prime Distance——素数筛法
- POJ 2689 素数筛法
- 几种素数筛法
- 素数筛法求素数(线性时间)
- POJ - 3126 Prime Path(BFS, 素数筛法)
- 短小精悍的线性时间素数筛法
- POJ 1007 Difference Between Primes(线性筛法求N以内的素数表)
- 用C语言实现素数筛法获取一亿(100000000)以内的全部素数
- 常见素数筛法
- 素数筛法
- Codeforces 385C Bear and Prime Numbers [素数筛法]
- 素数筛法
- HDU 4548 美素数 // 素数筛法
- hdu5391 Zball in Tina Town(素数筛法)
- 【并行计算】使用MPI实现简单的并行素数筛法
- 筛法求素数 (一般的线性筛法)
- 【bzoj2820】YY的GCD 线性筛法+莫比乌斯反演+数论分块
- leetcode---Count Primes---素数筛法的改进
- 神奇的线性筛法