1-n范围内的质数查找:埃拉托斯特尼筛法

news2024/9/25 9:35:20

文章目录

    • 质数查找思路
      • 质数定义
      • 代码思路
    • 写法
      • 重要逻辑:第一层for循环结束条件是i * i <= n而不是i<=n
      • 第二层循环如何筛查i所有倍数
    • 完整版:返回0-n正整数中所有质数
    • 时间复杂度
    • 例题
    • 参考资料:

质数查找思路

质数定义

质数是一个自然数,且除了1和它本身以外没有其他因数。换句话说,如果一个数大于1,且只有两个正因数(1和它本身),那么它就是一个质数。例如,2、3、5、7、11、13等都是质数。注意,1和0不是质数

根据质数的定义,质数p的倍数必然有其他因数(至少包括p本身),所以它们不可能是质数。因此,我们在使用埃拉托斯特尼筛法求质数时,对于每一个已知的质数p,都需要将所有p的倍数标记为非质数

例如,当p=2时,我们将所有2的倍数(即所有偶数)标记为非质数。然后,找到下一个还未被标记为非质数的数(即3),将所有3的倍数标记为非质数,以此类推。这样,剩下的未被标记的数就都是质数了。

在1–9范围内排查质数,遍历2和3的情况如图所示。

在这里插入图片描述

代码思路

代码方面的思路:

我们先定义一个is_prime数组 这个数组初始化为大小是n,初值全部是1

i从2到n开始遍历(因为0和1不是质数)。遇到不是质数的,就让对应的下标i的数值变成0,最后,得到的所有值是1的下标i就是n以内所有的质数

埃氏筛法是使用两层循环来判断0–N范围内的质数,第一层循环遍历小于等于n的所有数字,第二层循环对遍历到的数字,去除<=n范围内他们的所有倍数

写法

在1–n范围内,用埃拉托斯特尼筛法找出所有的质数的写法:

// 先设定一个数组,大小为n,初值全部为1
// 从2开始,对于每一个i,如果i是质数,那么i的所有倍数都不是质数
// 只需要检查到 sqrt(n) ,因为如果 n 不是质数,那么它必定有一个小于等于 sqrt(n) 的因子
for (int i = 2; i * i <= n; ++i) {
   if (is_prime[i]==1) {
      for (int j = i * 2; j <= n; j += i) {
          is_prime[j] = 0;
       }
   }
}

重要逻辑:第一层for循环结束条件是i * i <= n而不是i<=n

理论上来说,我们确实应该在第一层循环遍历所有数字。

但是,有一个基于数论的重要性质:如果一个数n不是质数那么它必然可以被某个小于等于sqrt(n)的数整除

某数字被x整除,就是指当前数字/x没有余数

例如,8不是一个质数,我们可以看到2和4是8的因数,2*4等于8,所以8可以被2和4整除。在这个例子中,sqrt(8)大约等于2.83,所以2是小于等于sqrt(8)的数,它可以整除8。实际上,对于任何非质数,我们总是可以找到至少一个小于等于它的平方根的因数

设想一下,如果一个数n不是质数,那么它至少有一对因数。设这对因数为a和b(a ≤ b)。如果a和b都大于sqrt(n)那么a * b将大于n,这与假设a和b是n的因数矛盾;同样,如果a和b都小于等于sqrt(n),那么a * b将小于n,也与假设矛盾。因此,对于n的任何一对因数,必然有一个小于等于sqrt(n),另一个大于等于sqrt(n)

因此,在埃拉托斯特尼筛法中,我们只需要检查到sqrt(n)就可以了

我们只需要将从2到sqrt(n)的所有数的倍数剔除就能得到所有的质数。这样也可以大大降低筛选质数的时间复杂度,使其在处理大规模数据时更高效。\

第二层循环如何筛查i所有倍数

筛所有倍数的逻辑:设定一个数字j,从j=i*2开始,每次循环j+=i,就是增加了一倍

for(int j=i*2;j<=n;j+=i)

通过这个逻辑寻找所有小于或等于n的i的倍数,然后将它们标记为非质数。

完整版:返回0-n正整数中所有质数

#include <vector>
#include <cmath>
using namespace std;

//返回0--n正整数中所有的质数
vector<int>judgePrime(int n){
    //包括0,所以要定义n+1
    vector<int>isPrime = (n+1,1);
    vector<int>result;
    //0和1不是质数
    isPrime[0]=isPrime[1]=0;
    //搜索i到sqrt(n)
    for(int i=2;i*i<=n;i++){
        if(isPrime[i]==1){
            for(int j=i*2;j<=n;j+=i){
                isPrime[j]=0;
            }
        }
    }
    //result就是isPrime数组中所有值为1的下标
    for(int i=2;i<=n;i++){
        if(isPrime[i]==1){
            result.push_back(i);
        }
    }
    return result;
    
}

时间复杂度

埃拉托斯特尼筛法的时间复杂度是O(n log log n)

这是因为在计算质数的时候,我们首先从2开始,然后找出2的所有倍数并将它们标记为非质数。然后,我们找到下一个仍然被标记为质数的数(在这个例子中是3),并找出3的所有倍数并将它们标记为非质数。我们继续这个过程,直到我们已经检查了所有小于等于sqrt(n)的数。由于每个数只被标记一次,所以总的操作次数是n/2+n/3+n/5+…这个级数的和近似为n log log n

例题

leetcode 6916.和等于目标的质数对2761. 和等于目标值的质数对 - 力扣(LeetCode)

给你一个整数 n 。如果两个整数 xy 满足下述条件,则认为二者形成一个质数对:

  • 1 <= x <= y <= n
  • x + y == n
  • xy 都是质数

请你以二维有序列表的形式返回符合题目要求的所有 [xi, yi] ,列表需要按 xi非递减顺序 排序。如果不存在符合要求的质数对,则返回一个空数组。

**注意:**质数是大于 1 的自然数,并且只有两个因子,即它本身和 1

示例 1:

输入:n = 10
输出:[[3,7],[5,5]]
解释:在这个例子中,存在满足条件的两个质数对。 
这两个质数对分别是 [3,7][5,5],按照题面描述中的方式排序后返回。

示例 2:

输入:n = 2
输出:[]
解释:可以证明不存在和为 2 的质数对,所以返回一个空数组。 

提示:

  • 1 <= n <= 10^6

解法:

class Solution {
public:
    vector<vector<int>> findPrimePairs(int n) {
        vector<vector<int>>result;
        
        vector<int>isPrime(n+1,1);
        isPrime[0]=0;
        isPrime[1]=0;
        //先调整i的数组,让数组里所有非质数下标对应的数值为0
        for(int i=2;i*i<=n;i++){
            if(isPrime[i]==1){
                for(int j=i*2;j<=n;j+=i){
                    isPrime[j]=0;
                }
            }
        }
        //在n以内找质数对
        for(int i=2;i<=n/2;i++){
            if(isPrime[i]==1&&isPrime[n-i]==1){
                //当我们试图创建一个一维向量加入二维数组,必须要用{}而不是[]
                result.push_back({i,n-i});//把质数对加入结果
            }
        }
        return result;
    }
};

参考资料:

算法数学知识总结

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

操作系统之调度算法总结

目录 一、进度调度算法 二、内存调度算法 一、先来先服务调度算法 二、最短寻道时间优先调度算法 三、扫描算法 四、循环扫描算法 五、LOOK和C-LOOK算法 三、内存页面置换算法 一、进度调度算法 常见的进度调度算法以及特点如下&#xff1a; 二、磁盘调度算法 一、先…

【大数据】初步认识StarRocks

StarRocks是什么 StarRocks 是新一代极速全场景 MPP 数据库。 StarRocks 充分吸收关系型 OLAP 数据库和分布式存储系统在大数据时代的优秀研究成果&#xff0c;在业界实践的基础上&#xff0c;进一步改进优化、升级架构&#xff0c;并增添了众多全新功能&#xff0c;形成了全新…

数据挖掘18大算法实现以及其他相关经典DM算法:决策分类,聚类,链接挖掘,关联挖掘,模式挖掘、图算法,搜索算法等

【机器学习入门与实践】入门必看系列&#xff0c;含数据挖掘项目实战&#xff1a;模型融合、特征优化、特征降维、探索性分析等&#xff0c;实战带你掌握机器学习数据挖掘 专栏详细介绍&#xff1a;【机器学习入门与实践】合集入门必看系列&#xff0c;含数据挖掘项目实战&…

TiDB(1):TiDB简介

1 从MySQL到TiDB 1.1 场景引入 假设现在有一个高速发展的互联网公司,核心业务库MySQL的数据量已经近亿行,且还在不断增长中,公司对于数据资产较为重视,所有数据要求多副本保存至少5年,且除了有对历史数据进行统计分析的离线报表业务外,还有一些针对用户数据实时查询的需求,如用…

软件测试技能,JMeter压力测试教程,签名sign(BeanShell 预处理程序)(二十)

前言 一般公司对外的接口都会用到sign签名&#xff0c;对不同的客户提供不同的apikey ,这样可以提高接口请求的安全性&#xff0c;避免被人抓包后乱请求 之前讲过用python代码实现sign签名&#xff0c;这次介绍jmeter上如何实现sign签名&#xff0c;思路都是差不多的 一、si…

Java框架之springboot基础

写在前面 本文看下springboot相关的基础内容。 1&#xff1a;从spring到springboot 在工作中&#xff0c;如果是我们想要引入某个框架&#xff0c;比如引入springMVC&#xff0c;就需要在web.xml中配置DispatcherServlet&#xff0c;在springmvc的配置文件中配置视图解析器等…

App自动化测试|Appium+Python自动化测试环境搭建

windows下搭建pythonappium环境 搭建过程步骤如下&#xff1a; 安装jdk并配置好环境变量&#xff08;jdk版本1.8以上&#xff09;安装android-sdk并配置好环境变量&#xff1b;具体步骤见&#xff1a;Android Studio安装(推荐使用这种方法安装SDK) - 环境配置 - 测试人社区安…

ASEMI代理海矽美SFP3012, 快恢复二极管SFP3012参数

编辑-Z SFP3012参数描述&#xff1a; 型号&#xff1a;SFP3012 最大反向重复峰值电压VRRM&#xff1a;1200V 平均整流正向电流IF&#xff1a;30A 反向恢复时间TRR&#xff1a;≤65nS 正向峰值浪涌电流IFSM&#xff1a;1602A 工作接点温度TJ&#xff1a;-40&#xff5e;1…

【数据挖掘】时间序列教程【七】

4.3 分布式滞后模型 考虑响应时间序列 y t 和输入(或“曝光”)时间序列 X t 。可能还有其他值得考虑的协变量,我们暂时忽略它们并在下一节中讨论它们的包含情况。我们将考虑以下形式的模型 在哪里 ε 表示独立同分布噪声过程。在连续时间设置中,该模型可以写为: …

VS上配置docker步骤记录

1:VS里安装Remote Development 2:运行 sudo usermod -aG docker $USER。#将当前用户添加到docker用户组中 sudo newgrp docker#更新,运行这个切到了root用户,获取权限 docker ps #列出正在运行的容器。它会显示容器的相关信息&#xff0c;如容器ID、镜像名称、创建时间、状态…

Linux 用户名称高亮和最近路径显示

1、通常情况下&#xff0c;Linux中的路径名称会不断叠加显示&#xff0c;如下图&#xff0c;这样看起来会很长。 2、为了设置路径只是当前最近的文件路径&#xff0c;先进入自己的家目录&#xff0c;然后进入.bashrc&#xff1a; 3、在.bashrc文件中的最后一行加入以下内容…

C# int[,] 和 int[,,]

如标题&#xff1b; 在C#中这两个是定义二维和三维数组的&#xff1b;这和C语言的写法不同&#xff1b; C语言定义二维数组是&#xff0c; int a[5][3]; 看下C#的多维数组&#xff1b;输出数组其中一个值&#xff1b; using System;class Program {static void Main(string[…

STM32 Proteus UCOSII系统拔河小游戏LED模拟-0053

STM32 Proteus UCOSII系统拔河小游戏LED模拟-0053 Proteus仿真小实验&#xff1a; STM32 Proteus UCOSII系统拔河小游戏LED模拟-0053 功能&#xff1a; 硬件组成&#xff1a;STM32F103R6单片机 1个选手1按键1个选手2按键1个重新开始按键7个LED灯1个蜂鸣器 1.单片机程序使用…

迷迷糊糊?似懂非懂?一文让你从此对SPI了如指掌

迷迷糊糊&#xff1f;似懂非懂&#xff1f;一文让你从此对SPI了如指掌 前言一、SPI 与 API1. SPI 在生活中的类比2. SPI 在代码上的例子3. API 与 SPI 的关系 二、JAVA 的 SPI 机制1. JAVA 中的 SPI 例子2. SPI 机制的四大组件3. SPI 机制的实现4. JAVA SPI的不足 前言 你是不…

CICD集合(四):Jenkins配置JDK,Maven,Allure报告

在Jenkins上面配置Jdk以及Maven环境 Maven和JDK Allure报告配置 当然配置Allure,得先安装Allure插件&#xff1a;

【Java项目】SpringBoot项目如何从自研配置中心拉取配置

文章目录 前言思路 前言 先简单说一下这个题目的意思是什么。 我们知道&#xff0c;如果我们的项目是SpringCloud的项目&#xff0c;我们是可以把我们的本地配置写到云端的的配置中心的&#xff0c;比如集成SpringCloud Alibaba&#xff0c;你就可以使用Nacos&#xff0c;然后…

科技云报道:智能化潮起,物联网产业链安全和效率问题何解?

科技云报道原创。 黑灯瞎火的夜。一胖一瘦两个小伙分别拿着平板和手机&#xff0c;在某知名新能源汽车周围鬼鬼祟祟地打转。 不到一分钟的时间&#xff0c;其中的瘦小伙很轻易地就用手机解开了车门锁。另外一名胖小伙&#xff0c;却用了两分钟&#xff0c;花了老大的力气&…

网站建设如何快速建站_网站建设快速建站有哪些方法

网站建设快速建站方法 1、JavaScript 压缩和模块打包 JavaScript 应用是以源码形式进行分发的&#xff0c;而源码解析的效率是要比字节码低的。对于一小段脚本来说&#xff0c;区别可以忽略不计。但是对于更大型的应用&#xff0c;脚本的大小会对应用启动时间有着负面的影响。…

dubbo Sentinet 限流 流控配置 高级 直连 关联 链路 预热冷启动 排队等待 单机 qps 并发 机器总体法制 单机均摊 集群俩种身份

目录 进入配置 单机超过10个限流 Qps 和 并发线程数区别使用思路 集群阈值模式 单机均摊 总体阈值 集群流控中共有两种身份&#xff1a; 高级-流控模式 直连 关联 链路 首先在实现类上加注解 Warm Up 预热冷启动 10秒内完成 100 预热并发效果 效果 排队等待 单…

Linux11.进程等待

1.写时拷贝 :使用fork创建子进程的时候&#xff0c;操作系统使用写时拷贝&#xff0c;类似于浅拷贝和深拷贝&#xff0c;对于只读的数据进行浅拷贝&#xff0c;对于需要写入的数据进行深拷贝。 2.cpu中有一个EIP寄存器&#xff0c;也叫pc指针(程序计数器)&#xff0c;永远指向…