筛选法的C++实现

 更新时间:2013年10月21日 09:24:49   作者:  
筛选法又称筛法,是求不超过自然数N(N>1)的所有质数的一种方法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛子

筛选法

介绍:
筛选法又称筛法,是求不超过自然数N(N>1)的所有质数的一种方法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛子。

具体做法是:先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊人是把数写在涂腊的板上,每要划去一个数,就在上面记以小点,寻求质数的工作完毕后,这许多小点就像一个筛子,所以就把埃拉托斯特尼的方法叫做“埃拉托斯特尼筛”,简称“筛法”。(另一种解释是当时的数写在纸草上,每要划去一个数,就把这个数挖去,寻求质数的工作完毕后,这许多小洞就像一个筛子。)

用C++实现筛选法:
以通过筛选法求100以内的素数为例

复制代码 代码如下:

#include<iostream>
using namespace std;
int main()
{
 int i,j,a[101];//这里定义101大小的数组,是为了和自然数相对应,即:a[2]对应自然数2
 for(i=2;i<100;i++)
     a[i]=1;//完成对数组的初始化操作
 for(i=2;i<100;i++){
  for(j=2*i;j<100;j+=i){
   a[j]=0;//对相应的倍数进行排除
  }
 }
 //执行输出操作
 for(i=2;i<100;i++){
  if(a[i])
  cout<<i<<'\t';
 }
 cout<<endl;
 return 0;
}

一些思考和优化
以前学习计算素数的算法的时候,有一个比较普遍的优化的算法。

也就是用

复制代码 代码如下:

for(i=1;i<(j/2);i++)

或者
复制代码 代码如下:

for(i=1;i<sqrt(j);i++)//使用sqrt()函数需要引入math.h这个头文件

来替代
复制代码 代码如下:

for(i=1;i<j;i++)

可以显著的降低算法的复杂度

一开始直接使用,不知道是什么原理。后来看了看,原来原理是这样的:

以sqrt(j)代替i为例

求素数最基本的方法,是用i去除以2到j-1之间的所有的整数,如果有可以整除的情况,则不是素数;如果都不可以整除,则是素数。

而i=sqrt(j)*sqrt(j)

我们用i去除以2到sqrt(j)之间的所有的整数,这就可以覆盖2到i-1之间的所有的整数。

设2<k<sqrt(j),则若j%k==0,则sqrt(j)<m=(j%k)<j-1。

也就是说,因为是除法运算求整除的运算,所以除以小的可以整除,可就是除以相应的大的可以整除。

优化之后的代码:

复制代码 代码如下:

#include<iostream>
#include<math.h>
using namespace std;
int main()
{
 int i,j,a[101];//这里定义101大小的数组,是为了和自然数相对应,即:a[2]对应自然数2
 for(i=2;i<100;i++)
     a[i]=1;//完成对数组的初始化操作
 for(i=2;i<sqrt(100);i++){
  for(j=2*i;j<100;j+=i){
   a[j]=0;//对相应的倍数进行排除
  }
 }
 //执行输出操作
 for(i=2;i<100;i++){
  if(a[i])
  cout<<i<<'\t';
 }
 cout<<endl;
 return 0;
}

相关文章

  • OpenGL实现鼠标移动方块

    OpenGL实现鼠标移动方块

    这篇文章主要为大家详细介绍了OpenGL实现鼠标移动方块,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-08-08
  • 浅谈C++中虚函数实现原理揭秘

    浅谈C++中虚函数实现原理揭秘

    下面小编就为大家带来一篇浅谈C++中虚函数实现原理揭秘。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-06-06
  • C++预定义的流对象基本示例详解

    C++预定义的流对象基本示例详解

    这篇文章主要为大家介绍了C++预定义的流对象基本示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • QT使用SQLite数据库超详细教程(增删改查、对大量数据快速存储和更新)

    QT使用SQLite数据库超详细教程(增删改查、对大量数据快速存储和更新)

    这篇文章主要给大家介绍了关于QT使用SQLite数据库的相关资料,其中包括增删改查以及对大量数据快速存储和更新,SQLite是一种嵌入式关系型数据库管理系统,它是一个软件库,提供了一个自包含、无服务器、零配置的、事务性的SQL数据库引擎,需要的朋友可以参考下
    2024-01-01
  • C++实战之二进制数据处理与封装

    C++实战之二进制数据处理与封装

    在电脑上一切数据都是通过二进制(0或1)进行存储的,通过多位二进制数据可以进而表示整形、浮点型、字符、字符串等各种基础类型数据或者一些更复杂的数据格式。本文将为大家详细讲讲二进制数据处理与封装,需要的可以参考一下
    2022-08-08
  • C++二分查找在搜索引擎多文档求交的应用分析

    C++二分查找在搜索引擎多文档求交的应用分析

    这篇文章主要介绍了C++二分查找在搜索引擎多文档求交的应用,实例分析了二分查找的原理与C++的实现及应用技巧,需要的朋友可以参考下
    2015-06-06
  • C++ socket通信遇到的问题及解决方法

    C++ socket通信遇到的问题及解决方法

    这篇文章主要介绍了C++ socket通信遇到的问题,通过代码修改来解决这个问题,本文结合实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2023-08-08
  • 用C语言模仿Python函数的实例

    用C语言模仿Python函数的实例

    下面小编就为大家带来一篇用C语言模仿Python函数的实例。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-05-05
  • 详解C++ 中 shared_ptr weak_ptr

    详解C++ 中 shared_ptr weak_ptr

    shared_ptr 是一个标准的共享所有权的智能指针,允许多个指针指向同一个对象,定义在 memory 文件中,命名空间为 std,这篇文章主要介绍了C++ 中 shared_ptr weak_ptr,需要的朋友可以参考下
    2022-07-07
  • C++之谈谈构造函数的初始化列表

    C++之谈谈构造函数的初始化列表

    构造函数主要作用在于创建对象时为对象的成员属性赋值,构造函数由编译器自动调用,无须手动调用,这篇文章详细介绍了构造函数的初始化列表,文章中有详细的示例代码,感兴趣的同学可以参考阅读
    2023-04-04

最新评论