图解Sieve of Eratosthenes(埃拉托斯特尼筛法)算法求解素数个数

1.素数的定义

  • 素数又称质数。
  • 质数是指在大于1的自然数中,除了1和它本身以外不再有其他因数的自然数。
  • 一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数;否则称为合数(规定1既不是质数也不是合数)。

2.问题引入:如何在数据规模较大的情况下高效的求解?

在这里插入图片描述

在这里插入图片描述

3.朴素解法

// 找出小于n的所有素数的方法
    public static List<Integer> findPrimes(int n) {
        List<Integer> primes = new ArrayList<>();

        for (int num = 2; num < n; num++) {
            if (isPrime(num)) {
                primes.add(num);
            }
        }

        return primes;
    }

    // 判断一个数是否为素数的方法
    private static boolean isPrime(int num) {
        if (num <= 1) {
            return false;
        }
        //注意这里只需要遍li到根号num即可
        //
        for (int i = 2; i * i <= num; i++) {
            if (num % i == 0) {
                return false;
            }
        }
        return true;
    }

在这里插入图片描述

在数据规模较大的情况下,这种暴力解法效率低下,是不可取的。

4.Sieve of Eratosthenes(埃拉托斯特尼筛法)

The sieve of Eratosthenes is one of the most efficient ways to find all primes smaller than n when n is smaller than 10 million or so.
埃拉托色尼筛法是找到小于n的所有质数的最有效方法之一当n小于1000万左右时。

When the algorithm terminates, all the numbers in the list that are not marked are prime.

当算法结束时,列表中所有未标记的数字都是素数。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

时间复杂度:n*log(log(n))

代码实现:

Java:

// Java程序,使用埃拉托斯特尼筛法打印小于或等于n的所有素数

class SieveOfEratosthenes {
    void sieveOfEratosthenes(int n)
    {
        // 创建一个布尔数组 "prime[0..n]" 并将所有条目初始化为true。
        // 如果prime[i]最终为false,则i不是素数,否则为true。
        boolean prime[] = new boolean[n + 1];
        for (int i = 0; i <= n; i++)
            prime[i] = true;
 
        // 使用埃拉托斯特尼筛法
        for (int p = 2; p * p <= n; p++) {
            // 如果prime[p]仍然为true,则p是素数
            if (prime[p] == true) {
                // 更新所有p的倍数,这些倍数大于或等于p的平方,
                // 且小于等于n的数已经被标记过了
                for (int i = p * p; i <= n; i += p)
                    prime[i] = false;
            }
        }
 
        // 打印所有素数
        for (int i = 2; i <= n; i++) {
            if (prime[i] == true)
                System.out.print(i + " ");
        }
    }
 
    // 主函数
    public static void main(String args[])
    {
        int n = 30;
        System.out.print("以下是小于或等于 " + n + " 的素数: ");
        SieveOfEratosthenes g = new SieveOfEratosthenes();
        g.sieveOfEratosthenes(n);
    }
}

C++:

// 使用埃拉托斯特尼筛法打印小于或等于n的所有素数的C++程序

#include <bits/stdc++.h>
using namespace std;
 
void SieveOfEratosthenes(int n)
{
    // 创建一个布尔数组 "prime[0..n]" 并将所有条目初始化为true。
    // 如果prime[i]最终为false,则i不是素数,否则为true。
    bool prime[n + 1];
    memset(prime, true, sizeof(prime));
 
    for (int p = 2; p * p <= n; p++) {
        // 如果prime[p]仍然为true,则p是素数
        if (prime[p] == true) {
            // 更新所有p的倍数,这些倍数大于或等于p的平方,
            // 且小于等于n的数已经被标记过了
            for (int i = p * p; i <= n; i += p)
                prime[i] = false;
        }
    }
 
    // 打印所有素数
    for (int p = 2; p <= n; p++)
        if (prime[p])
            cout << p << " ";
}
 
// 主函数
int main()
{
    int n = 30;
    cout << "以下是小于或等于 " << n << " 的所有素数:" << endl;
    SieveOfEratosthenes(n);
    return 0;
}

Python:

# 使用埃拉托斯特尼筛法打印小于或等于n的所有素数的Python程序

def SieveOfEratosthenes(n):
    # 创建一个布尔数组 "prime[0..n]" 并将所有元素初始化为True。
    # 如果prime[i]最终为False,则i不是素数,否则为True。
    prime = [True for i in range(n+1)]
    p = 2
    while (p * p <= n):

        # 如果prime[p]仍然为True,则p是素数
        if (prime[p] == True):

            # 更新所有p的倍数
            for i in range(p * p, n+1, p):
                prime[i] = False
        p += 1

    # 打印所有素数
    for p in range(2, n+1):
        if prime[p]:
            print(p)

# 主函数
if __name__ == '__main__':
    n = 20
    print("以下是小于或等于 {} 的素数:".format(n))
    SieveOfEratosthenes(n)

为什么埃拉托斯特尼筛法只需要从每个素数的平方开始标记?

  • 因为小于 (p^2) 的数,如果它们是合数,已经被之前的素数标记过了。
  • 这样做可以确保每个合数只被标记一次,提高算法的效率。

示例:

  1. 初始化: 创建一个布尔数组 is_prime,长度为 n+1,其中 n 是我们要找出的最大素数的范围。数组中的每个元素都初始化为 True,表示该索引对应的数是素数。

    对于找出小于或等于 30 的所有素数,创建长度为 31 的数组。

    is_prime = [True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True, True]
    
  2. 筛选过程: 开始从第一个素数 2 开始筛选。

    • 素数 2 是第一个素数,我们从 (2^2 = 4) 开始,将所有大于等于 4 的偶数标记为 False,因为它们都可以被 2 整除。具体操作是将数组中索引为 4、6、8、10、12、… 的位置置为 False

      is_prime = [True, True, True, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False, True, False]
      
    • 接下来,选择下一个未被标记为 False 的数,即素数 3,因为小于 (3的平方) 的数,如果它们是合数,已经被之前的素数标记过了,所以直接从 (3^2 = 9) 开始,标记所有大于等于 9 的数中可以被 3 整除的数为 False

      is_prime = [True, True, True, True, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, False, False, True, False, True, False]
      
    • 继续这个过程,选择下一个未被标记为 False 的数,即素数 5,从 (5^2 = 25) 开始,标记所有大于等于 25 的数中可以被 5 整除的数为 False

      is_prime = [True, True, True, True, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, True, False, False, False, True, False, False, False, True, False, True, False]
      
  3. 提取素数: 最终,所有仍为 True 的索引位置(除了 0 和 1)表示素数。素数是 2、3、5、7、11、13、17、19、23、29。


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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【绝对有用】刚刚开通的GPT-4o计算这种数学题目出现问题了

欢迎关注如何解决以上问题的方法&#xff1a;查看个人简介中的链接的具体解决方案

Nvidia Isaac Sim搭建仿真环境 入门教程 2024(4)

Nvidia Isaac Sim 入门教程 2024 版权信息 Copyright 2023-2024 Herman YeAuromix. All rights reserved.This course and all of its associated content, including but not limited to text, images, videos, and any other materials, are protected by copyright law. …

【iOS】#include、#import、@class、@import

文章目录 #include#importclassimport总结 #include #include是c\c中的预处理器指令&#xff0c;用于包含头文件的内容 但是使用#include可能会出现重复包含文件的问题&#xff0c;因此需要使用&#xff08;#ifndef/#define/#endif&#xff09;。 #import //导入系统头文件…

候选键的确定方法-如何判断属性集U的子集K是否为候选键、如何找到关系模式的候选键

一、候选键的定义 在关系模式R(U,F)中&#xff0c;若&#xff0c;且K满足&#xff0c;则K为关系模式R的候选键 关系模式R的候选键必须满足以下两个条件&#xff1a; &#xff08;1&#xff09;必须是属性集U的子集 &#xff08;2&#xff09;完全函数决定属性集U 二、如何…

【网络安全的神秘世界】已解决Failed to start proxy service on 127.0.0.1:8080

&#x1f31d;博客主页&#xff1a;泥菩萨 &#x1f496;专栏&#xff1a;Linux探索之旅 | 网络安全的神秘世界 | 专接本 | 每天学会一个渗透测试工具 解决burpsuite无法在 127.0.0.1&#xff1a;8080 上启动代理服务端口被占用以及抓不到本地包的问题 Burpsuite无法启动proxy…

令人震撼的人类智慧的科学领域-AI技术

AI&#xff0c;全称为人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;是一门致力于让机器模仿人类智慧的科学领域。其核心技术涵盖了机器学习、自然语言处理、计算机视觉及专家系统等多个方面。AI旨在开发能够感知环境、进行逻辑推理、自主学习并做出决策…

Python数据可视化:直方图、核密度估计图、箱线图、累积分布函数图

本文使用数据来源自2023年数学建模国赛C题&#xff0c;以附件1、附件2数据为基础&#xff0c;通过excel的数据透视表等功能重新汇总了一份新的数据表&#xff0c;从中截取了一部分数据为例用于绘制图表。绘制的图表包括一维直方图、一维核密度估计图、二维直方图、二维核密度估…

godot所有2D节点介绍

五十个2D节点介绍 2D节点介绍 前言一、Node2D二、sprite2D三、AnimatedSprite2D四、Camera2D五、PhysicsBody2D六、 RigidBody2D七、CharacterBody2D八、StaticBody2D九、joint2D十、DampedSpringJoint2D十一、GrooveJoint2D十二、PinJoint2D十三、Area2D十四、AnimatableBody2…

cloud_enum:一款针对不同平台云环境安全的OSINT工具

关于cloud_enum cloud_enum是一款功能强大的云环境安全OSINT工具&#xff0c;该工具支持AWS、Azure和Google Cloud三种不同的云环境&#xff0c;旨在帮助广大研究人员枚举目标云环境中的公共资源&#xff0c;并尝试寻找其中潜在的安全威胁。 功能介绍 当前版本的cloud_enum支…

kettle实时增量同步mysql数据

** 本文主要介绍运用kettle实时增量同步mysql数据 ** Debezium介绍 官网地址&#xff1a;https://debezium.io/documentation/ Debezium是一个开源项目&#xff0c;为捕获数据更改(Capture Data Change,CDC)提供了一个低延迟的流式处理平台&#xff0c;通过安装配置Debeziu…

[面试题]RabbitMQ

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis[面试题]Nginx[面试题]缓存[面试题]Redis[面试题]消息队列[面试题]…

科普文章:怎么远程监控电脑屏幕?三种监控电脑屏幕的方法

远程监控公司电脑屏幕是一项重要的管理手段&#xff0c;它不仅有助于提升工作效率&#xff0c;还能确保公司信息安全和合规性。随着远程办公的普及&#xff0c;这一需求变得日益重要。下面我将详细介绍几种实现远程监控公司电脑屏幕的方法&#xff0c;以及实施过程中需要注意的…

网络安全 DVWA通关指南 SQL Injection(SQL注入)

DVWA SQL Injection 文章目录 DVWA SQL InjectionLowMediumHighImpossible SQL注入漏洞基本原理 Web应用程序对用户输入的数据校验处理不严或者根本没有校验&#xff0c;致使用户可以拼接执行SQL命令。 可能导致数据泄露或数据破坏&#xff0c;缺乏可审计性&#xff0c;甚至导致…

机器学习案例|使用机器学习轻松预测信用卡坏账风险,极大程度降低损失

01、案例说明 对于模型的参数&#xff0c;除了使用系统的设定值之外&#xff0c;可以进行再进一步的优化而得到更好的结果。RM提供了几种参数优化的方法&#xff0c;能够让整体模型的效率提高。而其使用的概念&#xff0c;仍然是使用计算机强大的计算能力&#xff0c;对于不同…

01 Shell 编程规范与变量

目录 1.1 Shell脚本概述 1.1.1 Shell的作用 1.1.2 编写第一个Shell脚本 1.1.3 重定向与管道操作 1. 重定向操作 1. 重定向输出 2. 重定向输入 3. 错误重定向 2. 管代操作 1.2 Shell变量的作用、类型 1.2.1 自定义变量 1. 定义新的变量 2. 查看和引用变量的值 3. 变量赋值的特…

Django使用django-apscheduler实现定时任务

定时任务可以在后台定时执行指定的代码&#xff0c;避免了很多人为操作。下面是在Django项目中如何使用定时任务的具体操作流程。 我在这里使用的 django-apscheduler库来实现定时任务。 一、安装 django-apscheduler pip install django-apscheduler二、在项目的setting.py…

java.io.eofexception:ssl peer shut down incorrectly

可能是因为 1)https设置 2&#xff09;超时设置 FeignConfig.java package zwf.service;import java.io.IOException; import java.io.InputStream; import java.security.KeyStore;import javax.net.ssl.SSLContext; import javax.net.ssl.SSLSocketFactory;import org.apac…

PXE高效批量网络装机(补充) 实验部分

然后把防火墙、安全机制全都给关闭掉&#xff0c;不要让它们干扰后续的实验&#xff1a; 然后安装那几个需要用到的软件包&#xff1a; 如果重启了系统vsftpd是不能自动启动起来的&#xff0c;如果想让该服务每次开机都自动的启动起来&#xff0c;可以执行下图中的命令&#xf…

关系数据理论

什么是关系数据理论&#xff1a;用来评判数据库逻辑设计“好坏程度”的标准&#xff1b;二是如果逻辑设计中存在“不好”的关系模式&#xff0c;如何将其修改为“好”的关系模式。 函数依赖&#xff1a;举个例子:学生表中&#xff0c;一个学生的学生号确定了&#xff0c;学生的…

Arduino平台软硬件原理及使用——无源蜂鸣器模块的使用

文章目录 一、蜂鸣器发声原理 二、无源蜂鸣器与有源蜂鸣器的区分 三、无源蜂鸣器模块在Arduino中的使用 一、蜂鸣器发声原理 上图为常见的不同封装及规格的蜂鸣器。 同蜜蜂、知了等昆虫发声原理一样&#xff0c;蜂鸣器同样靠振动来发出声音&#xff1b; 如上图为无源蜂鸣器的内…