面向对象程序设计——埃拉托色尼筛法(C++)(已更新)
题目描述
在公元前3世纪,古希腊天文学家埃拉托色尼发现了一种找出不大于n的所有自然数中的素数的算法,即埃拉托色尼筛选法。这种算法能比比朴素的遍历法更快地找出素数,它首先需要按顺序写出2到n中所有的数。以n=20为例:
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
然后把第一个元素画圈,表示它是素数,然后依次对后续元素进行如下操作:如果后面的元素是画圈元素的倍数,就画X,表示该数不是素数。在执行完第一步后,会得到素数2,而所有是2的倍数的数将全被画掉,因为他们肯定不是素数。接下来,只需要重复上述操作,把第一个既没有被圈又没有画X的元素圈起来,然后把后续的是它的倍数的数全部画X。本例中这次操作将得到素数3,而所有是3的倍数的数都被去掉。以此类推,最后数组中所有的元素不是画圈就是画X。所有被圈起来的元素均是素数,而所有画X的元素均是合数。给定一个数字,编写一个程序实现埃拉托色尼筛选法找出小于或等于该数字的的所有素数。
【输入形式】
输入为一个正整数n, 2≤n≤2000000
【输出形式】
输出为一行,输出所有小于或等于输入的素数
数据之间用空格分隔
最后的一行输出后面无空格
【样例输入1】
5
【样例输出1】
2 3 5
【样例输入2】
20
【样例输出2】
2 3 5 7 11 13 17 19
解题思路(运行时间过长)
这道题要求使用埃拉托色尼筛法来做,即从第一个数2开始,对之后的数按照以下规则操作:
- 对从左开始,未被画×的数画圈
- 对之后的所有数中是该轮选定的画圈的数的倍数的数,画×
- 重新从左选择未被画×和圈的数画圈,重复操作2
这个操作映射到数组上,即用数字标志其状态,在这里初始状态均为0,画圈则为1,画×则为2,通过循环嵌套实现埃拉托色尼筛法。代码如下:
#include <iostream>using namespace std;
int judge(int a[],int n){ //判断是否所有元素已经画×或画圈for(int i=1;i<n;i++){if(a[i]==0) //若存在有元素未被判断,则返回1.return 1;}return 0;
}int main()
{int n;cin>>n;int a[2][n]; a[1][0]=2;int tem=1;int j;int count1=0; //为了满足输出的空格格式,统计共有多少数为质数。int counttem=0;for(int i=0;i<n;i++){ //初始化a[0][i] = i+1;a[1][i] = 0;}while(judge(a[1],n)){ //只要仍有元素未判断,则一直循环下去for(j=tem;j<n;j++){//从左寻找第一个未画圈、未画×的数if(a[1][j] ==0){a[1][j] = 1;count1++;tem = j;break;}}for(j=tem;j<n;j++){ //将该轮画圈的数的倍数画×if(a[0][j]%a[0][tem]==0 && j!=tem){a[1][j]=2;}}}for(j=1;j<n;j++){ //按照格式打印所有画圈的数if(a[1][j]==1){if(counttem<count1){ cout<<a[0][j]<<' ';counttem++;}else{cout<<a[0][j];}}}return 0;
}
改进
上述方法因为使用C风格的数组运行时间较长,并且考虑到当元素被画×之后,其实不需要再对其扫描一遍,只需要将其删除就好,在助教的提醒下,使用vector存储整性向量。
vector是C++特有的向量容器,可以存整型、字符等,具有size()、erase()等方法,可以直接调用,省去重复造轮子的时间。核心代码如下:
while(j<a.size()){//a为存储2~n的整型向量,这里size动态获取向量的长度i=j+1;//j为画圈的数,从画圈的下一个开始计算是否整除while(i<a.size()){if(a[i]%a[j]==0){a.erase(a.begin()+i);//删除该画×的元素,继续循环}else{i++;}}j++;}
这一次编译全部通过,而且代码量小了不少QAQ,还是要对C++的各种类熟悉一下嗷~
面向对象程序设计——埃拉托色尼筛法(C++)(已更新)相关推荐
- java面向对象程序设计编程题,已拿到offer
蚂蚁金服(五面) 蚂蚁金服:一面 一面就做了一道算法题,要求两小时内完成,给了长度为N的有重复元素的数组,要求输出第10大的数.典型的TopK问题,快排算法搞定. 算法题要注意的是合法性校验.边界条件 ...
- [.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用
[.net 面向对象程序设计进阶] (7) Lamda表达式(三) 表达式树高级应用 本节导读:讨论了表达式树的定义和解析之后,我们知道了表达式树就是并非可执行代码,而是将表达式对象化后的数据结构.是 ...
- 【软考】面向对象程序设计复习指南
1.根据考纲 (1)分析模式与设计模式知识 (2)面向对象程序设计知识 (3)用C++语言实现常见的设计模式及应用程序. (4)用Java语言实现常见的设计模式及应用程序. 2.面向对象基本概念 面向 ...
- 【Linux 中国】Simula 诞生之前的面向对象程序设计
Simula 诞生之前的面向对象程序设计 想象一下,你坐在河边,河岸上如茵绿草,不远处湍急河流:午后的阳光慵懒惬意,使人陷入冥想哲思,不觉开始思考眼前的河流是否真实存在.诚然,几米外确实有河水奔流而下 ...
- C++面向对象程序设计教程
前言 全篇使用标题+代码的形式,知识点的介绍写在代码部分的注释里.书籍为<C++面向对象程序设计教程(第四版)>(陈维兴 林小茶 编著). 第一章为基础概念,过于简单:第七章为输入输出流, ...
- C++《面向对象程序设计课程设计》
C++<面向对象程序设计课程设计> <面向对象程序设计课程设计>课程说明 适用专业:计算机科学与技术 课程周数:5周 一.根据计算机科学与技术专业人才培养方案制订. (一)课程 ...
- Java面向对象程序设计(OOP)
1.面向对象程序设计(OOP) 1.1.面向过程&面向对象 面向过程思想 步骤清晰简单,第一步做什么,第二步做什么-(线性思维) 面向过程适合处理一些较为简单的问题 面向对象编程 物以类聚,分 ...
- [.net 面向对象程序设计进阶] (27) 团队开发利器(六)分布式版本控制系统Git——在Visual Studio 2015中使用Git...
[.net 面向对象程序设计进阶] (26) 团队开发利器(六)分布式版本控制系统Git--在Visual Studio 2015中使用Git 本篇导读: 接上两篇,继续Git之旅 分布式版本控制系统 ...
- C++大作业(面向对象程序设计大作业)——销售公司员工管理
面向对象程序设计大作业 目录 面向对象程序设计大作业 1.问题重述 2.编程思想 2.1数据结构 2.2功能确定 3.类的设计 3.1UML图标准 3.2本题类图 4.运行结果 1.输出所有信息 2. ...
最新文章
- 【Qt】Log4Qt(一)下载、编译
- 如何在Java 环境下使用 HTTP 协议收发 MQ 消息
- 网易云信牵手有道乐读,解密「终身阅读者」背后的技术力量
- [导入][转]sap学习手册二
- LeetCode 1776. 车队 II(单调栈)
- Libcurl的介绍
- lnmp解析php,搭建LNMP,可以解析PHP文件-Go语言中文社区
- 《HTML5和JavaScript Web应用开发》——第 2 章 移动Web 2.1移动优先
- 荣耀20 Pro正面渲染图曝光:开孔全面屏设计+后置四摄
- argparse模块用法
- Detours信息泄漏漏洞
- 51驱动AD9833
- mkv文件怎样转成mp4
- tensorflow的数据读取 tf.data.DataSet、tf.data.Iterator
- Mac OS X 10.8.5升级到更高版本的方法
- 北大培训课动态规划----神奇的口袋(百练2755)
- 搭建大型分布式服务(十四)SpringBoot整合dubbo starter
- 弘辽科技:大裁员之后,京东最新财报来了
- seo策略_调整移动用户的SEO策略
- Flash Player帧频、Timer计时 的时间间隔
热门文章
- LaTeX Subfigure 中间添加垂直线
- 如何在CSS和HTML中创建垂直线...
- GIS小白教程:如何利用高程DEM数据构建三维地图模型(基于ArcScene)
- Kubernetes 部署高可用集群(二进制,v1.18)下
- 干货 | 关于离岸银行开户(境外开户),看这一篇就够了
- 2023年起,社保断缴1次,这些资格待遇通通取消,一定要注意!
- 计算机丢失opencv_world300.dll文件
- 『现学现忘』Docker相关概念 — 1、云计算概念
- 嵌入式入门学习笔记2
- 成人世界的规则,越早了解,越早受益