埃氏筛法(快速筛选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是否为素数就可以了...

 

posted @ 2015-07-26 20:17  Recoder  阅读(6716)  评论(0编辑  收藏  举报