我所知的素数筛选法
2016-04-12 11:06
351 查看
素数筛选法在很多大牛的博客中都有帖子,有的甚至给出3种方法。。。本文只是给我自己和能看到这篇文章的人分享一下我个人理解到现在的素数筛选法。
素数筛选法常常的问题背景是给出一个非负整数n,求小于(等于)n的非负整数内有几个素数。
下面先给出素数筛选法的原理:开出一个大小为n的bool型数组arr,全置为false。此时用数组下标(0 to n-1)来代表小于等于n的全部非负整数。而其中某个数值arr[i]代表这个数是否为合数,即一开始我们假设所有数是素数。不做任何优化的素数筛选,第一层循环index == 2 to n -1。第二层不断倍增index(index*2 index*3...),这样新得到的下标一定是合数,将其内容置true。这里有三个注意的地方,一是注意下标不要越界,二要注意第一层循环要判断当前位置数组的内容,如果已经被置为true,证明有更小的index1
* j == index,则index倍增的结果都可以由index1倍增得到,此时再去倍增index是徒劳的。三是0和1既不是合数也不是素数本身不参与倍增和个数统计。为了方便理解,我从LEETCODE上一道有关素数筛选的题目搞到一张解释素数筛选过程的图如下
下面给出以c++实现的代码
开帖方便自己随时回炉。如果对大家有帮助就更好了,也不是什么大神,只能搞搞这种小问题。。。
素数筛选法常常的问题背景是给出一个非负整数n,求小于(等于)n的非负整数内有几个素数。
下面先给出素数筛选法的原理:开出一个大小为n的bool型数组arr,全置为false。此时用数组下标(0 to n-1)来代表小于等于n的全部非负整数。而其中某个数值arr[i]代表这个数是否为合数,即一开始我们假设所有数是素数。不做任何优化的素数筛选,第一层循环index == 2 to n -1。第二层不断倍增index(index*2 index*3...),这样新得到的下标一定是合数,将其内容置true。这里有三个注意的地方,一是注意下标不要越界,二要注意第一层循环要判断当前位置数组的内容,如果已经被置为true,证明有更小的index1
* j == index,则index倍增的结果都可以由index1倍增得到,此时再去倍增index是徒劳的。三是0和1既不是合数也不是素数本身不参与倍增和个数统计。为了方便理解,我从LEETCODE上一道有关素数筛选的题目搞到一张解释素数筛选过程的图如下
下面给出以c++实现的代码
int countPrimes(int n) { vector<bool> res(n, false); for(int i = 2;i < n;++i){ if(!res[i]){ for(int j = 2;i*j < n;++j){ res[i*j] = true; } } } int count = 0; for(int i = 2;i < n;++i){ if(!res[i]) ++count; } return count; }这里可以做一些优化,全部是围绕有且只有一个偶素数2.其他偶数可以不参与筛选和最后的素数个数统计,代码如下:
int countPrimes(int n) { vector < bool > res(n, false); for (int i = 3; i < n; i += 2) {//从3开始筛选,i+=2保证了只关心奇数 if (!res[i]) { for (int j = 3; i * j < n; j += 2) {//倍增的时候也跳过2及2的倍数,保证倍增的结果也是奇数 res[i * j] = true; } } } int count = n >= 3 ? 1 : 0;//统计时根据问题规模决定count中包不包括2 for (int i = 3; i < n; i += 2) {//这里统计也只关心奇数 if (!res[i])++count; } return count; }这就是我想分享的结果啦。。。优化的代码跑leetcode测试用例时常减少了一半还多。。。开心
开帖方便自己随时回炉。如果对大家有帮助就更好了,也不是什么大神,只能搞搞这种小问题。。。
相关文章推荐
- 深拷贝与浅拷贝
- Java Stack遍历与Vector关系
- android开发 greendao学习及使用笔记
- 指定的命名连接在配置中找不到、非计划用于 EntityClient 提供程序或者无效
- [Unity3D]图形渲染优化、渲染管线优化、图形性能优化
- Android上传文件至服务器
- Win8安装.NET 3.5
- 使用Github SSH Key来避免Hexo部署时输入账户密码
- 解决gem不能使用的问题
- PAT 月饼
- 线程池原理浅析
- tomcat使用redis共享session并实现单点登录
- Jquery跨域获得Json(三)
- 理解 i++ 和++i
- 【leetcode】238. Product of Array Except Self
- Assets.xcassets的详细使用方法
- ceph的一些优化
- Unity 插值运算 Vector3.Lerp(transform.position, targetPos, smoothing * Time.deltaTime);
- [iOS] 如何改变一个控制器的大小?
- 【转】部署web项目到weblogic上启动错误