首页 > 编程语言 >《算法笔记》系列----质数的判断(埃氏筛法)

《算法笔记》系列----质数的判断(埃氏筛法)

时间:2024-03-30 19:32:42浏览次数:17  
标签:埃氏 筛法 int 质数 素数 sqrt ---- 算法 复杂度

目录

一、朴素算法

二、埃氏筛法

1、与朴素算法对比

2、算法介绍    

3、例题即代码实现


一、朴素算法

  从素数的定义中可以知道,一个整数n要被判断为素数,需要判断n是否能被2.3.n- 1中的一个整除。只2,3..n- 1都不能整除n,n才能判定为素数,而只要有一个能整除n的数出现,n就可以判定为非素数。
        这样的判定方法没有问题,复杂度为0(n)。但是在很多题目中,判定素数只是整个算法
中的一部分,这时候0(n)的复杂度实际上有点大,需要更加快速的判定方法。注意到如果在
2 ~n-1中存在n的约数,不妨设为k,即n%k=0,那么由k*(n/k)=n可知,n/k也是n的一个约数,且k与n/k中一定满足其中一个小于等于sqrt(n)、另一个大于等于sqrt(n)其中sqr(n)为根号n。这启发我们,只需要判定n能否被2, 3,.. sqrt(n)中的一个整除(具中x表示对x向下取整),即可判定n县否为素数。这样的话时间复杂度就位o( sqrt(n))

代码如下:

bool isprime(int x){
  for(int i=2;i*i<=x;i++){
     if(x%i==0){
     return false;
       }
     }
      return true;
}

这里有个东西要注意:c++中sqrt函数是对double类型的函数,但是在实际代码中传进来的一般是一个int类型的数,因此我们在使用时要像下面这样让x乘上一个1.0

int main(){
   int x;
   cin>>x;
   ifprime(sqrt(1.0*x));
   
}

二、埃氏筛法

1、与朴素算法对比

      上面这个算法在判断一个数是否是素数时时间复杂度优越,但是如果我们这个题目需要得到在这个数范围内所有的素数(素数表)时这个时间复杂度就偏大,即o(nsqrt(n))

2、算法介绍    

      因此我们要隆重引入我们新的算法埃氏筛法:

当需要生成一个给定范围内所有素数的素数表时,可以采用更高效的算法来降低时间复杂度。一种常见的方法是使用埃拉托斯特尼筛法(Sieve of Eratosthenes)

        埃氏筛法的时间复杂度O(nlog(log(n))),明显优于逐个判断每个数是否为素数的O(nsqrt(n)​)复杂度。

埃拉托斯特尼筛法的基本思想是从2开始,依次将每个素数的倍数标记为非素数,直到遍历完整个范围。剩下未被标记的数即为素数。

整理步骤如下:

  1. 初始化一个布尔数组,表示每个数是否为素数,初始值为True。
  2. 从2开始遍历到n​,对于每个素数p,将其倍数p×k(其中k>1)标记为非素数。
  3. 遍历完整个范围后,未被标记的数即为素数。

这种方法在生成素数表时能够显著减少时间复杂度,是常用的高效算法之一。

3、例题即代码实现

链接-晴问算法:https://sunnywhy.com/sfbj/5/4/205

完整ac代码:

 

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    vector<bool> isprime(n+1,true);
    for(int i=2;i<=n;i++){
        if(isprime[i]){
            for(int j=i+i;j<=n;j+=i){
                isprime[j]=false;
            }
            cout<<i<<endl;
        }
    }
    return 0;
}

标签:埃氏,筛法,int,质数,素数,sqrt,----,算法,复杂度
From: https://blog.csdn.net/2301_77961281/article/details/137158884

相关文章

  • (七)Rust 通用的编程概念
    变量与可变性在Rust语言中,声明变量是使用let关键字,而且变量默认是不可改变的,一旦值被绑定在一个名称上,就不能给这个变量重新赋值,如果重新赋值的话,就会在编译的时候报错。这是Rust提供给我们的众多优势之一,让我们可以充分利用Rust提供的安全性和简单并发性来编写代码......
  • (八)Rust 函数和注释
    函数在Rust里,声明函数使用fn关键字,按照惯例,针对函数和变量名,Rust使用snakecase命名规范:所有的字母都是小写,单词之间使用下划线分开,例如:函数的参数定义函数时里边定义的参数,叫形参(parameters)调用函数时传递的具体参数,叫实参(arguments)在函数签名里,必须声明每个参数的类......
  • web复现
    怎么请求来着bp抓包,修改请求方法后放行 查看源代码得到flag爆炸吧小黑子用户名admin,密码123,尝试登录并抓包使用所给字典爆破 找到长度不一样的为密码登录后得到flag 诶? bp抓包,使用X-Forwarded-For伪造IP地址zaiyong 再将浏览器修改为WLGF_Yunxi_604最......
  • elementui 导航菜单栏和Breadcrumb 面包屑关联
    系列文章目录一、elementui导航菜单栏和Breadcrumb面包屑关联文章目录系列文章目录前言一、elementui导航菜单栏和Breadcrumb面包屑怎么关联?二、实现效果三、实现步骤1.本项目演示布局2.添加面包屑2.实现breadcrumbName方法3.监听方法4.路由指配5.路由配置信息四......
  • c语言:用do-while输出前40项的斐波那契数值
    求Fibonacci数列的前40个元素。该数列的特点是第1、2两个数为1、1。从第3个数开始,每数是其前两个数之和。  分析:从题意可以用如下等式来表示斐波那契数列:     1,1,2,3,5,8,13,21…     f1=1     (n=1)     f2=1   ......
  • Vim常用命令大全
    分四个模式:        1.命令模式(默认进入到的)        2.编辑模式(按i/a即可编辑模式)        3.末行模式(一般按1次/2次ESC按键,再输入冒号即可进入)        4.可视化模式(命令模式按v即可进入)命令转换图如下图所示:1.命令模式      ......
  • 基于Arduino的RFID智能门禁
    引言RFID(无线射频识别)技术作为现代物联网的重要组成部分,已经广泛应用于门禁、支付、物流等众多领域。本文将带领大家使用Arduino开发板和RFID读写模块,实现RFID卡片的刷卡识别功能。百度网盘链接经过优化后的代码,删掉了没用的那些代码,并且将代码整合到了一个文件中。链接......
  • 通信专业毕业设计(论文)-基于移动通信的网络的发展和故障诊断
    下载请点击↓:通信专业毕业设计(论文)-基于移动通信的网络的发展和故障诊断资源-CSDN文库毕业设计(论文)基于移动通信的网络的发展和故障诊断学生姓名                      专业班级                       ......
  • JAVA学习-网络编程.Java11标准化的HTTP Client
           Java11引入了标准化的HTTPClient,它提供了一种现代化、灵活且易于使用的方式来进行HTTP通信。下面是关于Java11标准化的HTTPClient的概述以及与其他比较和高级应用的说明:1.概述:       Java11标准化的HTTPClient是一种替代HttpURLConnection的新......
  • Node+Vue毕设在线问诊系统(程序+mysql+Express)
    本系统(程序+源码)带文档lw万字以上 文末可获取本课题的源码和程序系统程序文件列表系统的选题背景和意义选题背景:随着互联网医疗的兴起,在线问诊系统作为一种新型的医疗服务模式,受到了广泛关注。它通过提供远程医疗咨询、病情评估和健康指导等服务,极大地方便了患者就医,缓......