埃筛法统计素数个数

这里记录一下用埃筛法统计素数个数的算法:

一般来说,统计从0到某一个数含有多少个素数,我们一般都会暴力求解,就是从2开始一直遍历,看某个数是否有因数。但其实,这样的算法效率并不是很高。因为比如说,我统计出2是素数,那么这个时候,我还有没有必要去遍历2×2,2×3,2×4...是不是素数呢?显然是没有的。那么埃筛法其实就是基于这样的一个思想,减少了不必要的遍历次数。

刚开始,我们先初始化一个数组,里面的元素全部为0,假设0代表某个数是素数,那么这样初始化也就表示这个数组里面的所有元素全部都是素数,然后,我们从2开始遍历,只要这个数组里面对应的值是1,我就计数器自增一次,然后把从这个数能得到的所有数在数组中的值修改为1(这里有点绕,具体看代码就懂了).那么下次遍历的时候就不会遍历到这些数了。

 1 #include <iostream>
 2 #include <cstdbool>
 3 #define N 1000
 4 using namespace std;
 5 int aikoin(int n)
 6 {
 7     int flag[N] = { 0 };
 8     int count = 0;
 9     for (int i = 2; i < n; ++i) {
10         if (!flag[i]) {
11             ++count;
12             for (int j = i * i; j < n; j += i) {
13                 flag[j] = 1;
14             }
15         }
16     }
17     return count;
18 }
19 int main()
20 {
21     int n;
22     cout << "输入一个数:";
23     cin >> n;
24     int res = aikoin(n);
25     cout << "从1到" << n << "共有" << res << "个素数" << endl;
26     return 0;
27 }

可以看到,数组初始化全部是0,if语句只会让是0的那些数让count自增,然后把合数全部弄为1了。也就是说,只有初始值是0的时候,count才会加加,也就是我们前面约定好了的0代表素数。if语句让是0的数过。

至于if语句里面的for循环,由于i是外部变量,不能在里面进行自增操作,所以我们用点小技巧,让j每次加上i的值再进入循环,这样相当于找出了i往上的每一个合数。要是不懂的话,可以自己动手模拟一下循环过程。

 

 

posted @ 2021-07-11 16:44  EvanTheBoy  阅读(186)  评论(0编辑  收藏  举报