埃筛法统计素数个数
这里记录一下用埃筛法统计素数个数的算法:
一般来说,统计从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往上的每一个合数。要是不懂的话,可以自己动手模拟一下循环过程。