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

news2024/11/29 4:44:25

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.coloradmin.cn/o/1844518.html

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

相关文章

(day1)数据类型详解及DML语句入门

一、数据类型 1、整型类型 &#xff08;1&#xff09;创建数据库 CREATE DATABASE ql_linux&#xff1b; CREATE SCHEMA IF NOT EXISTS ql_linux&#xff1b; //IF NOT EXISTS如果没有表就创建 SHOW DATABASE; //查看数据库 &#xff08;2&#xff09;创建表 C…

C语言变量、指针的内存关系

1. type p ? 表示从内存地址p开始&#xff0c;开辟一段内存&#xff0c;内存大小为类型type规定的字节数&#xff0c;然后把等号右边的值写入到这段内存中。 因此&#xff0c;这块内存起点位置是p&#xff0c;结束是ptype字节数-1。 2. type* p ?表示从内存地址p开始&…

算法:分治(归并)题目练习

目录 题目一&#xff1a;排序数组 题目二&#xff1a;数组中的逆序对 题目三&#xff1a;计算右侧小于当前元素的个数 题目四&#xff1a;翻转对 题目一&#xff1a;排序数组 给你一个整数数组 nums&#xff0c;请你将该数组升序排列。 示例 1&#xff1a; 输入&#xf…

Tailwindcss 提取组件

背景 随着项目的发展&#xff0c;您不可避免地会发现自己需要重复使用常用样式&#xff0c;以便在许多不同的地方重新创建相同的组件。这在小组件&#xff08;如按钮、表单元素、徽章等&#xff09;中最为明显。在我的项目中是图表标题样式如下&#xff1a; <div class&qu…

14-Kafka-Day03

第 5 章 Kafka 消费者 5.1 Kafka 消费方式 5.2 Kafka 消费者工作流程 5.2.1 消费者总体工作流程 一个消费者组中的多个消费者&#xff0c;可以看作一个整体&#xff0c;一个组内的多个消费者是不可能去消费同一个分区的数据的&#xff0c;要不然就消费重复了。 5.2.2 消费者…

SpringSecurity6从入门到实战之登录后操作

SpringSecurity6从入门到实战之登录后操作 上次已经了解了如何进行自定义登录页面,这次主要是详细讲解登录成功,登录之后的跳转以及包括退出登录等一系列操作.让我们来看看SpringSecurity需要如何进行配置 登录之后的跳转 定义 Spring Security 配置类 Configuration EnableW…

数据治理的七大核心技术 全面了解数据治理必读篇

在当今的数字化时代&#xff0c;数据已成为企业最宝贵的资产之一&#xff0c;其价值不仅体现在数据量的巨大&#xff0c;更在于数据的深度和宽度。随着大数据、云计算、物联网&#xff08;IoT&#xff09;和人工智能&#xff08;AI&#xff09;等技术的不断进步&#xff0c;企业…

25考研线代攻略,老师及习题册推荐!

其实很多经验贴对大家有一定的误导 网上很多人说李永乐讲的好&#xff0c;确实好&#xff0c;但是没有说听李永乐的线代需要一定的基础 于是很多人去听完李永乐&#xff0c;就懵逼了&#xff0c;这讲的很乱啊&#xff0c;听的一头雾水。 其实&#xff0c;李永乐的基础班授课…

天才简史——Diederik P. Kingma与他的Adam优化器

一、了解Diederik P. Kingma 发生日期&#xff1a;2024年6月18日 前几日&#xff0c;与实验室同门一同前往七食堂吃饭。饭间&#xff0c;一位做随机优化的同门说他看过一篇被引18w的文章。随后&#xff0c;我表示不信&#xff0c;说你不会数错了吧&#xff0c;能有1.8w次被引都…

智慧城市低空+AI视频智能监控:构建新时代安全防线

随着科技的飞速发展&#xff0c;智能监控技术已经广泛应用于各个领域&#xff0c;从城市治理到工业生产&#xff0c;从公共安全到环境监测&#xff0c;都发挥着越来越重要的作用。而在低空领域&#xff0c;AI视频智能监控方案的建设更是成为了一个热点话题。 一、低空AI视频智…

Java异常和文件

一、异常 1.定义 异常&#xff1a;异常就是代表程序出现的问题 体系结构&#xff1a; 最上层的是 Throwable 类&#xff0c;下面有两个子类&#xff1a; ① Error&#xff1a;代表系统级别的问题&#xff08;属于严重问题&#xff0c;比如&#xff1a;内存溢出&#xff09;。…

VScode基本使用

VScode下载安装&#xff1a; Visual Studio Code - Code Editing. Redefined MinGW的下载安装&#xff1a; MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.net x86是64位处理器架构&#xff0c;i686是32为处理器架构。 POSIX和Win32是两种不同的操…

java文件传输小工具 java17+springboot3+thymeleaf

背景 在和同事工作中经常需要传输文件&#xff0c;但是公网传输太慢&#xff0c;业务方不是计算机专业直接用命令行沟通麻烦。 本小工具通过页面可视化方便用户使用&#xff0c;端口9090&#xff0c;启动默认展示当前登陆本机用户的桌面。 代码开源&#xff1a; https://git…

SM9加密算法:安全、高效的国产密码技术

随着信息技术的飞速发展&#xff0c;网络安全问题日益凸显。加密算法作为保障信息安全的核心技术&#xff0c;受到了广泛关注。在我国&#xff0c;一种名为SM9的加密算法逐渐崭露头角&#xff0c;凭借其卓越的安全性能和高效计算能力&#xff0c;成为了新一代国产密码技术的代表…

NGINX_九 nginx_proxy代理

九 nginx_proxy代理 1.代理 1.1 代理原理 反向代理产生的背景&#xff1a; 在计算机世界里&#xff0c;由于单个服务器的处理客户端&#xff08;用户&#xff09;请求能力有一个极限&#xff0c;当用户的接入请求蜂拥而入时&#xff0c;会造成服务器忙不过来的局面&#xff0…

使用Jetpack Compose和DummyJSON加速你的Android开发

使用Jetpack Compose和DummyJSON加速你的Android开发 在现代Android开发中&#xff0c;Jetpack Compose提供了一种全新的UI构建方式&#xff0c;同时DummyJSON简化了开发过程中数据获取的复杂性。本文将详细介绍一个名为firefly-compose的Jetpack Compose模板应用程序&#xf…

电脑一键还原系统,小白也能轻松操作!

电脑一键还原系统是一项非常实用的功能&#xff0c;当电脑遇到无法解决的问题或需要恢复到出厂设置时&#xff0c;用户可以通过一键还原功能快速恢复系统到之前的状态。这项功能不仅可以节省时间&#xff0c;还能有效解决系统问题。本文将介绍三种电脑一键还原系统的方法&#…

【React】Lodash---groupBy() 分组

例子 _.groupBy([6.1, 4.2, 6.3], Math.floor); // > { 4: [4.2], 6: [6.1, 6.3] }// The _.property iteratee shorthand. _.groupBy([one, two, three], length); // > { 3: [one, two], 5: [three] }思路分析 来源 定义一个名为groupBy的方法&#xff0c;通过扩展Ar…

AI界的“视频滤镜”(Stable Diffusion进阶篇-TemporalKit视频风格转化),手把手教你制作原创AI视频

大家好&#xff0c;我是向阳 在之前的文章中我也分享过如何进行AI视频的制作&#xff0c;说是AI视频其实也就是通过Stable Diffusion进行视频重绘&#xff0c;也就是将一个视频一帧一帧重绘为自己想要的画面&#xff0c;然后再连贯起来成为视频。 这个东西其实比较耗费时间和…

智能猫砂盆是养猫必需品吗?三个好用品牌让你实现铲屎自动化!

随着现代社会的快节奏和压力增大&#xff0c;许多人开始因工作、旅行或其他紧急情况需要暂时离家&#xff0c;但这样的话&#xff0c;大家又要如何确保猫咪的猫砂盆在无人照料的情况下依旧保持清洁&#xff1f;尤其在炎热的季节&#xff0c;猫砂盆若长时间未得到清理&#xff0…