欧拉筛和埃氏筛(超详细分析筛选过程,差异,证明,时间比较)

分析之前我们先看一下埃氏筛和欧拉筛的代码:

1.Eraosthenes(埃拉托斯尼筛法)埃氏筛法

时间复杂度O(nlogn)

const int maxn=2e6+6;
bool isprime[maxn];
void seive(){memset(isprime,true,sizeof(isprime));isprime[0]=isprime[1]=false;for(int i=2;i<=maxn-6;i++){if (isprime[i]) {for (int j = i * i; j <= maxn-6; j += i) {isprime[j] = false;}}}
}

2.欧拉筛法

时间复杂度O(n)

const int N = 1e8 + 3;
bool isprime[N];
int prime[N],cnt;
void ola(int n) {memset(isprime, true, sizeof(isprime));isprime[1] = 0;for (int i = 2; i <= n; i++) {if (isprime[i]) prime[++cnt] = i;//如果i没有被前面的数筛掉,则i是素数for (int j = 1; j<=cnt&&prime[j] <= n/i; j++) {//j枚举已经筛出的素数,该循环起到筛掉枚举素数的倍数的作用isprime[i * prime[j]] = 0;//把i*prime[j]筛掉if (i % prime[j] == 0) break;//保证不会重复筛}}
}

详细筛选过程:

埃氏筛:

假如要筛选素数的范围为1~20000

用isprime[i] 来表示 i 是否为素数

首先把所有的 isprime[] 里面的值都置为true

首先对于0 和 1 设置为false 表示不为质数

用 i 表示从 2 遍历到20000 如果 i 是 素数就进行操作

大体进行流程:


从2开始

将2*2、3*2、4*2、5*2、、、、、、10000*2 所有得到的值

isprime[i] 置为false 表示他们都不是素数


然后从3开始

将2*3、3*3、4*3、5*3、、、、、、6666*3 所有得到的值

isprime[i] 置为false 表示他们都不是素数


然后从4开始(注意这里的4不是素数,故不进行筛选)


然后从5开始

将2*5、3*5、4*5、5*5、、、、、、4000*5 所有得到的值

isprime[i] 置为false 表示他们都不是素数


、、、、、、


最后从20000结束循环(注意这里的20000不是素数,故不进行筛选)


最终我们得到的所有的isprime[i] 里面为true 的即为素数

欧拉筛:

假如要筛选素数的范围为1~20000

用isprime[i] 来表示 i 是否为素数

首先把所有的 isprime[] 里面的值都置为true

首先对于0 和 1 设置为false 表示不为质数

用 i 表示从 2 遍历到20000 如果 i 是 素数就进行操作

(操作:对于每一个 i 乘上已经得到的所有素数,如果遇见了i 可以整除的质数,跳出循环,对于i+1进行操作)

大体进行流程:


从2开始

将2*2得到的值

isprime[i] 置为false 表示他都不是素数


从3开始

将2*3、3*3得到的值

isprime[i] 置为false 表示他都不是素数


从4开始

将2*4得到的值(注意这里对于3*4没有进行筛选,因为4可以整除2,那么就不需要筛后面的数)

isprime[i] 置为false 表示他都不是素数


从5开始

将2*5、3*5、5*5得到的值

isprime[i] 置为false 表示他都不是素数


 、、、、、、


从20000结束循环(因为2*20000大于我们要找的范围,故直接退出)


最终我们得到的所有的isprime[i] 里面为true 的即为素数

为什么欧拉筛会比埃氏筛更快:

对于埃氏筛:

大家很容易就可以发现在筛的过程中例如对于6就有重复的筛选。而这一些重复的筛选就使我们筛选的过程中出现的时间的浪费。

对于欧拉筛:

欧拉筛效率高的原因:不重复筛选

欧拉筛特点:合数都是被它的最小素因子筛去的

由上面两点我们就可以得到欧拉筛在筛的时候,将埃氏筛重复筛的过程跳过了,这样就使欧拉筛的时间消耗更小。

筛法做法正确简单证明:

埃氏筛:

例如对于 i=11 ,我们循环 i 到 11 的时候可以直接判断它为素数

原因:

前面所有比11 小的质数 例如2 、3、5、7 都已经把

他们能乘出来的所有合数都筛掉了

那么我们遍历到11的时候就可以直接判断它是否是合数了

欧拉筛:

欧拉筛是从1~20000遍历一遍

然后每一次遍历的时候和所有已经筛出来的素数相乘

虽然和埃氏筛的筛法不一样

但从总体来看我们可以发现筛选的数和埃氏筛差不多

只是去掉了重复的部分:(对于合数能够整除质数的退出操作保证了不会对重复数据进行筛选)

Devc++ 1~20000筛选时间比较:(左为埃氏筛,右为欧拉筛)

埃氏筛代码:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;const int maxn=2e6+6;
const int N=20000;
bool isprime[maxn];void seive(){memset(isprime,true,sizeof(isprime));isprime[0]=isprime[1]=false;for(int i=2;i<=N;i++){if (isprime[i]) {for (int j = i * i; j <= N; j += i) {isprime[j] = false;}}}
}int main(){seive();int sum=0;for(int i=1;i<=20000;i++){if(isprime[i]){sum++;if(sum%5==0){printf("%d\n",i);}else{printf("%d ",i);}}}return 0;
}

欧拉筛:

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;const int maxn=2e6+6;
const int N=20000;
bool isprime[maxn];
int prime[N];
int cnt;void ola(int n) {memset(isprime, true, sizeof(isprime));isprime[1] = 0;for (int i = 2; i <= n; i++) {if (isprime[i]) prime[++cnt] = i;//如果i没有被前面的数筛掉,则i是素数for (int j = 1; j<=cnt&&prime[j] <= n/i; j++) {//j枚举已经筛出的素数,该循环起到筛掉枚举素数的倍数的作用isprime[i * prime[j]] = 0;//把i*prime[j]筛掉if (i % prime[j] == 0) break;//保证不会重复筛}}
}int main(){ola(20000);int sum=0;for(int i=1;i<=cnt;i++){if(i%5!=0)cout<<prime[i]<<" ";elsecout<<prime[i]<<endl;}return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/111758.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

目标检测中生成锚框函数详解

%matplotlib inline import torch from d2l import torch as d2l torch.set_printoptions(2) # 让pytorch打印张量时&#xff0c;只打印到小数点后两位将设一张图片&#xff0c;宽和高为2,2 X torch.rand(size(1,3,2,2)) Y generate_anchors(X,sizes[0.75,0.5,0.25],ratios[…

webpack配置alias后eslint和ts无法识别

背景 我们在 webpack 配置 alias 后&#xff0c;发现项目中引入的时候&#xff0c;还是会报错&#xff0c;如下&#xff1a; 可以看到&#xff0c;有一个是 ts报错&#xff0c;还有一个是 eslint 报错。 解决 ts 报错 tsconfig.json {"compilerOptions": {...&q…

基于Xml方式的Bean的配置-Bean的作用范围scope配置

SpringBean的配置详解 Bean的配置范围 默认情况下&#xff08;基本的Spring环境&#xff09;&#xff0c;单纯Spring环境Bean的作用范围有两个&#xff1a;Singleton和prototypesingleton:单例&#xff0c;默认值&#xff0c;Spring容器创建的时候&#xff0c;就会进行Bean的实…

TCP详解之流量控制

TCP详解之流量控制 发送方不能无脑的发数据给接收方&#xff0c;要考虑接收方处理能力。 如果一直无脑的发数据给对方&#xff0c;但对方处理不过来&#xff0c;那么就会导致触发重发机制&#xff0c;从而导致网络流量的无端的浪费。 为了解决这种现象发生&#xff0c;TCP 提…

专注写作,快速上线:Cpolar+Inis帮助你在Ubuntu上建立博客网站

文章目录 前言1. Inis博客网站搭建1.1. Inis博客网站下载和安装1.2 Inis博客网站测试1.3 cpolar的安装和注册 2. 本地网页发布2.1 Cpolar临时数据隧道2.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;2.3.Cpolar稳定隧道&#xff08;本地设置&#xff09; 3. 公网访问测试总…

LeetCode-热题100-笔记-day31

105. 从前序与中序遍历序列构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/ 给定两个整数数组 preorder 和 inorder &#xff0c;其中 preorder 是二叉树的先序遍历&#xff0c; inorder 是同一棵树的中序遍历&#xff0c…

使用 Docker 安装 Elasticsearch (本地环境 M1 Mac)

Elasticsearchkibana下载安装 docker pull elasticsearch:7.16.2docker run --name es -d -e ES_JAVA_OPTS“-Xms512m -Xmx512m” -e “discovery.typesingle-node” -p 9200:9200 -p 9300:9300 elasticsearch:7.16.2docker pull kibana:7.16.2docker run --name kibana -e EL…

区域图片上色

目录 下图中&#xff0c;记得点击Apply&#xff0c;然后再点击Symbology 实际选择的时候&#xff0c;不选1Categorized&#xff0c;因为其分段不方便。

现在全国融资融券两融利率最低是多少?哪家证券公司券商费率低?

融资融券是指投资者通过向券商借入资金&#xff08;融资&#xff09;或借入证券&#xff08;融券&#xff09;&#xff0c;以达到获得更高收益、降低交易风险、提高资金利用效率的目的。通过融资&#xff0c;投资者可以用借入的资金买入更多的证券&#xff1b;通过融券&#xf…

C#,数值计算——Hashtable的计算方法与源程序

1 文本格式 using System; using System.Collections; using System.Collections.Generic; namespace Legalsoft.Truffer { public abstract class Hashtable<K> { private int nhash { get; set; } private int nmax { get; set; } pr…

使用ROS与Movelt实现myCobot 280运动轨迹规划和控制

ROS的技术案例 Introduction 今天这篇文章将记录我使用myCobot 280 M5stack 在ROS当中是如何使用的。为什么使用ROS呢&#xff0c;因为提及到机器人都离不开ROS这个操作系统&#xff0c;今天是我们第一次使用ROS这个系统。 今天我将从ROS的介绍&#xff0c;环境的配置以及mycob…

JDK8源码阅读环境配置

说明 环境 jdk 版本&#xff1a;1.8.0_381 系统&#xff1a;macos 13.5.1 Intel 目的 学习 jdk8 源码&#xff0c;并能自定注释。 新建 java 工程 在 idea 中新建 java 工程&#xff0c;注意并非 maven 工程。如下图&#xff1a;完成后&#xff0c;如下图&#xff1a; 配置…