埃氏筛法(快速筛选n以内素数的个数)

给你一个数n,请问n以内有多少个素数?(n <= 10e7)

一般来说,要是对一个整数进行素数判断,首先想到的是写个函数判断是否为素数,然后调用这个函数,时间复杂度为O(n^(½)),但是要求n以内的素数就略显吃力了.

要是求n以内的素数个数的话,可以用埃式筛选.预处理一下.

先看下面的代码:

 1 /*
 2     |埃式筛法|
 3     |快速筛选素数|    |15-7-26|
 4 */
 5 #include <iostream>
 6 #include <cstdio>
 7 using namespace std;
 8 const int SIZE = 1e7;
 9
10 int prime[SIZE];            // 第i个素数
11 bool is_prime[SIZE];    //true表示i是素数
12
13 int slove(int n)
14 {
15     int p = 0;
16     for(int i = 0; i <= n; i++)
17         is_prime[i] = true;             //初始化
18     is_prime[0] = is_prime[1] = false;      //0,1不是素数
19     for(int i = 2; i <= n; i++)
20     {
21         if(is_prime[i])                //这里比较巧妙, 我只是意会
22         {
23             prime[p++] = i;             //计算素数的个数,也记录下了素数
24             for(int j = 2 * i; j <= n; j += i)      // 除掉了i的倍数的数字
25                 is_prime[j] = false;
26         }
27     }
28     return p;
29 }
30
31 int main()
32 {
33     int n;
34     while(cin >> n)
35     {
36         int res = slove(n);
37         cout << res << endl;
38         for(int i = 0; i < res; i++)
39             cout << prime[i] << endl;
40     }
41 }
2 3 4 5 6 7 8 9 10 11 12
2 3 - 5 - 7 - 9 - 11 -
2 3 - 5 - 7 - - - 11 -

结合这张表看看,慢慢一次次的都筛选完了..

其中最小的素数是2,将表中所有2的倍数都除去,剩下最小的数是3,不能被更小的数整除,所以是素数.再将表中3的倍数的数除去.以此类推.如果表中最小的数字是m,m就是素数.然后将表中所有m的倍数都除去...然后就可以了= =

话说要是求区间[x,y]内求素数个数的话,只要0~y的素数个数-0~x的素数个数就可以了,然后判断x是否为素数就可以了...

这是我写的第一篇文章,写的不好,有错误的话,望请指点.

时间: 2024-10-20 20:01:24

埃氏筛法(快速筛选n以内素数的个数)的相关文章

埃氏筛法(求n以内有多少个素数)

题目大意:给定整数n,请问n以内有多少个素数 思路:想必要判断一个数是否是素数,大家都会了,并且可以在O(根号n)的复杂度求出答案,那么求n以内的素数呢,那样求就显得有点复杂了,下面看一下这里介绍的??氏算法 其实呢,就是求出第一个素数,然后把n以内它的倍数都删掉就行了,很简单.然后找下一个素数,同样方法····· 看代码 #include<iostream> #include<string.h> #include<map> #include<cstdio>

埃氏筛法&amp;欧拉筛法

埃氏筛法 /* |埃式筛法| |快速筛选素数| |15-7-26| */ #include <iostream> #include <cstdio> using namespace std; const int SIZE = 1e7; int prime[SIZE]; // 第i个素数 bool is_prime[SIZE]; //true表示i是素数 int slove(int n) { int p = 0; for(int i = 0; i <= n; i++) is_p

素数的快速筛选(埃氏筛法)

要枚举n以内的素数,可以用埃氏筛法.这是一个与辗转相除法一样古老的算法. 首先,将2到n范围内的所有整数写下来.其中最小的数字2是素数.将表中所有2的倍数都划去.表中剩余的最小数字是3,它不能被更小的数整除,所以是素数.再将表中所有3的倍数全都划去.依次类推,如果表中剩余的最小数字是m时,m就是素数.然后将表中所有m的倍数全部划去.像这样反复操作,就能依次枚举n以内的素数. int prime[maxn];//第i个素数 bool is_prime[maxn];//is_prime[i]为tru

埃氏筛法(素数筛)

埃式筛法:给定一个正整数n(n<=10^6),问n以内有多少个素数? 做法:做法其实很简单,首先将2到n范围内的整数写下来,其中2是最小的素数.将表中所有的2的倍数划去,表中剩下的最小的数字就是3,他不能被更小的数整除,所以3是素数.再将表中所有的3的倍数划去……以此类推,如果表中剩余的最小的数是m,那么m就是素数.然后将表中所有m的倍数划去,像这样反复操作,就能依次枚举n以内的素数,这样的时间复杂度是O(nloglogn). 题解:如果要是按照一个一个判断是否是素数然后把ans+1,时间复杂度

数论_埃氏筛法(求区间内多少素数)

埃拉托斯特尼(公元前276-公元前194) 埃拉托斯特尼是古希腊著名的数学家.地理学家.天文学家.他先在亚历山大港学习,后又转至雅典.公元前236年,托勒密三世指定他为亚历山大图书馆的图书管理员和馆长.他跟阿基米德是好朋友.埃拉托斯特尼的主要贡献包括: 埃拉托斯特尼筛法:寻找素数的方法. 地理常数测量:日地间距的测量(现在称一个这样的距离为一个天文单位).地月间距的测量.测量赤道与黄道之间的偏角.地球半径测量等. 精确地图绘制:当时只有托勒密等级的人物能绘出同等级的地图. 算法数学原理:埃拉托斯

分拆素数和 埃氏筛法

分拆素数和 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2098 Description 把一个偶数拆成两个不同素数的和,有几种拆法呢? Input 输入包含一些正的偶数,其值不会超过10000,个数不会超过500,若遇0,则结束. Output 对应每个偶数,输出其拆成不同素数的个数,每个结果占一行. Sample Input 30

埃氏筛法之素数

原理: 首先将2~n个数记录下来,2作为最小素数,所以2的倍数不是素数,从记录中划去,扫一遍之后,将3作为最小素数,3的倍数划去,如此下去,求出所有素数.如表格所示: 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 3 - 5 - 7 - 9 - 11 - 13 - 15 - 17 - 19 - 2 3 - 5 - 7 - - - 11 - 13 - - - 17 - 19 - 代码: 判断是否是素数: bool is_prime(int n

素数的计算-埃氏筛法(区间素数利器)

素数,各种素数,各种题总是遇到素数. 下面我们来说一下求素数的一种比较有效的算法. 就是筛法.因为这个要求得1-n区间的素数只需要O(nloglogn)的时间复杂度. 下面来说一下它的思路. 思路:现在又1-n的数字,素数嘛就是除了1和本身之外没有其他的约数,所以有约数的都不是素数. 我们从2开始往后遍历,是2的倍数的都不是素数,所以我们把他们划掉 然后现在从2往后就是3了 因为3的前面没有能整除3的,所以3是素数,然后3的倍数全都不是素数,我们接着划掉. 然后就是5了,因为4是2的倍数不是素数

埃氏筛法

埃氏筛法,理解起来很好理解,就是在1~n这n个连续的数里面开始筛出合数,知道剩下全部为素数,大致流程如下: 第一步:能够确定1不是素数,所以将1筛出,剩下从2开始的数列 第二步:找到2为第一个素数,那么遍历这个数列,将2的倍数筛出,形成一个新的数列 第三步:找到下一个素数 x,此时 x = 3,那么再次遍历这个数列,筛出 x 的倍数,剩下的数再次形成一个新的数列 第四步:重复第三步,直到将所有合数筛出 代码如下: #include <iostream> #include <cstring