筛法求素数
来源:互联网 发布:蜡烛图分析软件 编辑:程序博客网 时间:2024/05/25 21:33
筛法求素数
假设要求n以内的素数
筛法求素数是用一个大小为n的数组,作为标记数组,如果没被标记到则为素数。
开始均为未标记。
从2开始,2没被标记,将2存入一个存素数的地方,然后筛掉小于n的,2的所有倍数。然后是3,筛掉3的所有倍数,依此类推,直到n-1。
优化
上面的做法,同一个数可能会被筛掉多次,比如6会被3和2各筛一次。
为了提高效率,需要进行优化,使得每个数尽可能的被少筛,如果能一次最好。
考虑到任何合数都可以分解成若干个素数的乘积。在筛掉合数的过程中,最好的是让每个合数只被它最小的因子筛掉。
如24 18 都只被2筛掉
C++实现
int countPrimes(int n) { vector<bool> vis(n,false); vector<int> prime; for(int i=2;i<n;i++){ if(!vis[i]) prime.push_back(i); for(int j=0;j<prime.size() && i*prime[j]<=n;j++){ vis[i*prime[j]] = true; if(i%prime[j] == 0) break; //优化 } } return prime.size(); }
最外层循环每次循环,都能得到小于等于i的所有素数,当要求i+1内的素数时,只需判断i+1是否在之前被筛掉。
与此同时,将当前所有素数的i+1倍筛掉。
那后面出现的素数的i+1倍,设为m ,会怎么样呢?
- 如果i+1是素数,m会被 i+1 筛掉
- 如果i+1不是素数,则m 会被i+1的最小质因数(之前出现过的素数中的某一个)筛掉。
优化点:每个数都被它最小的因数筛掉
具体操作:如果循环到某个素数 prime[j] 是 i+1的倍数时,后面的素数的i+1倍 prime[j+1] * (i+1)
就不用筛了。
原因在于:后面素数的i+1倍一定会被 prime[j] (更小的一个数)筛掉,
阅读全文
0 0
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- 筛法求素数
- pthread 主线程子线程退出关系
- java数据类型、存储以及作为方法参数传递
- MyBatis Generator(MBG)提供的插件
- 最近公共祖先(最简单算法)
- 数据库sql语句
- 筛法求素数
- Volley网络框架详解
- linux 如何杀掉 tty终端
- [LintCode]407.加一
- LeetCode-13Sum
- ASP.NET Core服务器综述
- Java实现:利用栈进行后缀表达式计算实例
- Python的基础知识点(二)
- 自定义复选框,复选框样式修改,重写复选框