java输出1~100之间的全部素数的5种方法

2023-10-27


一、前言

在我们面试或者初学java 会遇到 请用java输出1~100的所有素数,这样一道问题,这道题有很多的解法,接下来我们将讲解其中的 5种方案:

二、需求分析

2.1 . 什么是素数?

经查询小学二年级的数学课本可知:

  • 只能被1和本身整除的称为素数

2.2 分析

判断是不是素数的方法很多,但不外乎是循环嵌套外加条件语句; 故我们可以分析出以下判断条件:

  1. 判断条件1:只能被1和本身整除的称为素数;
  2. 判断条件2:在区间(1,x/2)中找不到能整除素数x的整数;
  3. 判断条件3:在区间(1,sqrt(x))中找不到能整除素数x的整数;

三、代码实现

3.1 方法一:根据素数的定义来遍历检查

这种方案也是最简单,最容易想到的方法。

    /**
     * 方法一:根据素数的定义来遍历检查
     */
    private static void method1() {

//外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
        for (int i = 2; i <= 100; i++) {
//定义一个逻辑值,初值为true
            boolean flag = true;
//内层遍历除数j
            for (int j = 2; j < i; j++) {
//判断是否存在j能整除i,若存在,则更改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
//根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

3.2 方法二:根据判断条件2进行遍历检查,减少遍历次数

    /**
     * 方法二:根据判断条件2进行遍历检查,减少遍历次数
     * 外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
     */
    private static void method2() {

        for (int i = 2; i <= 100; i++) {
            //定义一个逻辑值flag,初始值为true
            boolean flag = true;
            //内层循环遍历除数j(注意:此处若不取边界,则当i=4时,j=2会因为小于i/2=2而直接跳出内循环)
            for (int j = 2; j <= (i / 2); j++) {
                //判断是否存在除数j能整除i,若存在,则修改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
            //根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

3.3 方法三:根据判断条件3进行遍历检查,减少遍历次数

    /**
     * 方法三:根据判断条件3进行遍历检查,减少遍历次数
     * 外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
     */
    private static void method3() {

        for (int i = 2; i <= 100; i++) {
//定义一个逻辑值flag,初始值为true
            boolean flag = true;
//内层循环遍历除数j(注意:此处若不取边界,则当i=4时,j=2会因为小于sqrt(i)=2而直接跳出内循环)
//再思考一下若i=25时呢?若不取边界还有那些不是素数的数会输出呢?
            for (int j = 2; j <= Math.sqrt(i); j++) {
//判断是否存在除数j能整除i,若存在,则修改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
//根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

3.4 方法四:在方法三的前提上优化,优化基础是除2外的所有偶数均不是素数

    /**方法四:在方法三的前提上优化,优化基础是除2外的所有偶数均不是素数,
     *(i+=2)只遍历奇数,减少外层遍历次数;同理,由于奇数是不能被偶数整除的,
     *(j+=2)只遍历奇数,减少内层遍历次数
     */
    private static void method4() {

        System.out.print("2 ");
        //外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
        for (int i = 3; i <= 100; i += 2) {
            //定义一个逻辑值flag,初始值为true
            boolean flag = true;
            //内层循环遍历除数j(注意:此处若不取边界,则当i=4时,j=2会因为小于sqrt(i)=2而直接跳出内循环)
            //再思考一下若i=25时呢?若不取边界还有那些不是素数的数会输出呢?
            for (int j = 3; j <= Math.sqrt(i); j += 2) {
                //判断是否存在除数j能整除i,若存在,则修改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
            //根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

3.5 方案五:优化更长的素数计算

联想一下,能被2整除(偶数)的直接剔除,同样的道理,能被3or5整除的剔除掉会不会让外层循环的次数更少呢?此处才到100,若是1000呢?10000呢?定义一个数组,由于剔除了偶数,故数组长度不会超过总个数的一半。

    /**
     * 联想一下,能被2整除(偶数)的直接剔除,同样的道理,能被3or5整除的剔除掉会不会让外层循环的次数更少呢?
     * 此处才到100,若是1000呢?10000呢?
     * 定义一个数组,由于剔除了偶数,故数组长度不会超过总个数的一半
     */
    private static void method5() {
        int[] arr = new int[500];
        int count = 0;
        for (int i = 6; i <= 1000; i++) {
            boolean flag = true;
            if (0 == i % 2 || 0 == i % 3 || 0 == i % 5) {
                flag = false;
            }

            if (flag) {
                arr[count] = i;
                count++;
            }
        }
        System.out.println("6~1000中剔除能被2or3or5整除的数后还剩" + count + "个");
        System.out.println("1~1000中所有素数为:");
        System.out.print("2" + "\t");
        System.out.print("3" + "\t");
        System.out.print("5" + "\t");
        count = 0;
        for (int i = 0; i < 500; i++) {
            boolean flag = true;
            if (0 == arr[i]) {
                break;
            }

            for (int j = 7; j <= Math.sqrt(arr[i]); j += 2) {
                if (0 == (arr[i]) % j) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                System.out.print((arr[i]) + "\t");
                count++;
            }
        }
        System.out.println("\n" + "---------------------");
        System.out.println("\n" + "其中6~1000中剔除能被2or3or5整除的数中还是素数的有" + count + "个");
    }

四、完整的代码实现

package com.ratel.skywalking.order;
/*
分析:
1.素数:
判断条件1:只能被1和本身整除的称为素数;
判断条件2:在区间(1,x/2)中找不到能整除素数x的整数;
判断条件3:在区间(1,sqrt(x))中找不到能整除素数x的整数;
2.方法:很多,但不外是循环嵌套外加条件语句;
*/
class PrintSuShu {
    public static void main(String[] args) {
        method1();
        method2();
        method3();
        method4();
        method5();


    }

    /**
     * 联想一下,能被2整除(偶数)的直接剔除,同样的道理,能被3or5整除的剔除掉会不会让外层循环的次数更少呢?
     * 此处才到100,若是1000呢?10000呢?
     * 定义一个数组,由于剔除了偶数,故数组长度不会超过总个数的一半
     */
    private static void method5() {
        int[] arr = new int[500];
        int count = 0;
        for (int i = 6; i <= 1000; i++) {
            boolean flag = true;
            if (0 == i % 2 || 0 == i % 3 || 0 == i % 5) {
                flag = false;
            }

            if (flag) {
                arr[count] = i;
                count++;
            }
        }
        System.out.println("6~1000中剔除能被2or3or5整除的数后还剩" + count + "个");
        System.out.println("1~1000中所有素数为:");
        System.out.print("2" + "\t");
        System.out.print("3" + "\t");
        System.out.print("5" + "\t");
        count = 0;
        for (int i = 0; i < 500; i++) {
            boolean flag = true;
            if (0 == arr[i]) {
                break;
            }

            for (int j = 7; j <= Math.sqrt(arr[i]); j += 2) {
                if (0 == (arr[i]) % j) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                System.out.print((arr[i]) + "\t");
                count++;
            }
        }
        System.out.println("\n" + "---------------------");
        System.out.println("\n" + "其中6~1000中剔除能被2or3or5整除的数中还是素数的有" + count + "个");
    }

    /**方法四:在方法三的前提上优化,优化基础是除2外的所有偶数均不是素数,
     *(i+=2)只遍历奇数,减少外层遍历次数;同理,由于奇数是不能被偶数整除的,
     *(j+=2)只遍历奇数,减少内层遍历次数
     */
    private static void method4() {

        System.out.print("2 ");
        //外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
        for (int i = 3; i <= 100; i += 2) {
            //定义一个逻辑值flag,初始值为true
            boolean flag = true;
            //内层循环遍历除数j(注意:此处若不取边界,则当i=4时,j=2会因为小于sqrt(i)=2而直接跳出内循环)
            //再思考一下若i=25时呢?若不取边界还有那些不是素数的数会输出呢?
            for (int j = 3; j <= Math.sqrt(i); j += 2) {
                //判断是否存在除数j能整除i,若存在,则修改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
            //根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

    /**
     * 方法三:根据判断条件3进行遍历检查,减少遍历次数
     * 外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
     */
    private static void method3() {

        for (int i = 2; i <= 100; i++) {
//定义一个逻辑值flag,初始值为true
            boolean flag = true;
//内层循环遍历除数j(注意:此处若不取边界,则当i=4时,j=2会因为小于sqrt(i)=2而直接跳出内循环)
//再思考一下若i=25时呢?若不取边界还有那些不是素数的数会输出呢?
            for (int j = 2; j <= Math.sqrt(i); j++) {
//判断是否存在除数j能整除i,若存在,则修改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
//根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

    /**
     * 方法二:根据判断条件2进行遍历检查,减少遍历次数
     * 外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
     */
    private static void method2() {

        for (int i = 2; i <= 100; i++) {
            //定义一个逻辑值flag,初始值为true
            boolean flag = true;
            //内层循环遍历除数j(注意:此处若不取边界,则当i=4时,j=2会因为小于i/2=2而直接跳出内循环)
            for (int j = 2; j <= (i / 2); j++) {
                //判断是否存在除数j能整除i,若存在,则修改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
            //根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }

    /**
     * 方法一:根据素数的定义来遍历检查
     */
    private static void method1() {

//外层循环遍历被除数i(因为1既不是素数也不是和数,所以直接从2开始遍历)
        for (int i = 2; i <= 100; i++) {
//定义一个逻辑值,初值为true
            boolean flag = true;
//内层遍历除数j
            for (int j = 2; j < i; j++) {
//判断是否存在j能整除i,若存在,则更改flag的值并跳出循环
                if (0 == i % j) {
                    flag = false;
                    break;
                }
            }
//根据flag的值判断是否输出i
            if (flag) {
                System.out.print(i + " ");
            }
        }
        System.out.println('\n' + "---------------------------");
    }
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java输出1~100之间的全部素数的5种方法 的相关文章

  • 从现实抽象出类的步骤

    第一 找出分类 分析出类 第二 找出类的特征 分析类的相关属性 第三 找出类的行为 分析类的方法 转载于 https www cnblogs com liumeilin p 7018110 html

随机推荐

  • AVRCP协议介绍

    文章目录 1 AVRCP协议介绍 1 2 概念 1 2 1 1 2 2 role 用途 2 AVRCP框架 1 AVRCP协议介绍 1 2 概念 1 2 1 1 2 2 role CT controller 是一种通过向目标发送命令帧来启动
  • 静态编译和动态编译,java与javascript区别总结

    1 静态编译和动态编译 静态编译是程序在编译时就已经确定好了所有类之间的关系 要运行程序所有类 都缺一不可 若在开始运行时就把其中的某类文件丢失 就会产生 NoClassDefFoundError错误 程序会终止 在程序运行前的装载期间就把
  • flutter获取状态栏高度

    获取状态栏高度 import dart ui MediaQueryData fromWindow window padding top 系统默认的appBar等高度 位于Dart Packages flutter src material
  • 物理渲染学习笔记(三)——Cook-Torrance微表面模型

    从 Phong 到 GGX 光照模型林林总总 一直没能找机会梳理一遍 这几天依次都自己实现了一遍 也正好总结下 Microfacet 普通的着色模型假设着色的区域是一个平滑的表面 表面的方向可以用一个单一的法线向量来定义来定义 而 Micr
  • 程序员吃青春饭?程序员在35岁以后是否需要转行?你规划好了吗?

    都说程序员是一个吃青春饭的职业 都认为程序员到了35岁以后不转管理岗位就没有什么前途了 可能就要考虑换别的行业了 年龄越大可能越写不动代码了 那么程序员是不是35岁以后需要转行 我说说我自己的观点 关于程序员35岁之后是不是要转行这个问题
  • 区块链技术基础(笔记)

    一 区块链本质上是一个对等网络 peer to peer 的分布式账本数据库 二 区块链本身其实是一串链接的数据区块 其链接 指针是采用密码学哈希算法对区块头进行处理所产生的区块头哈希值 三 基本概念 1 数据区块 比特币的交易会保存在数据
  • Element ui 导航栏 刷新时高亮

    1 在组件中
  • 原理解析:JS 代码是如何被浏览器引擎编译、执行的?

    原理解析 JS 代码是如何被浏览器引擎编译 执行的 分析浏览器引擎对 JS代码的编译情况 并结合日常的 JavaScript开发经验 重新理解底层的编译解析机制 对其底层原理的理解 将有助于理解前端的跨端应用 以及一套代码生成多种小程序相关
  • csu 1809 Parenthesis 2016湖南省赛 G

    Problem acm csu edu cn csuoj problemset problem pid 1809 vjudge net contest 161962 problem G Reference blog csdn net l95
  • spring之bean注入的意义

    简而言之就是 首先 service注解在当前类的上边 表示在当前类是spring管理的一个bean 使用 autowired 将另外一个A类的实体bean注入到当前类中 让当前类具备那个A类的功能
  • Android SDK & AVD Manager

    0 前言 Android源码中的prebuilts devtools tools android程序可根据不同的参数来启动SDK Manager或AVD Manager 1 SDK Manager 1 启动 android or andro
  • Chrome 基于 Wappalyzer 查看网站所用的前端技术栈

    1 找到谷歌商店 https chrome google com webstore search wappalyzer utm source ext app menu 2 搜索 Wappalyzer 3 添加至Chrome 4 使用 插件
  • MySQL的脏读、幻读、不可重复读

    首先我们要知道 我们的脏读 幻读 不可重复读这些概念是在事务中的概念 脏读 也就是读取了未提交的数据 比如我开启了一个事务A 在里面操作一个用户表 获取里面一个用户的积分 比如此时这个用户的积分是100 此时有另外一个事务B也操作了这个用户
  • LD3320语音识别

    芯片介绍 LD3320 不需要外接任何辅助的Flash芯片 RAM芯片和AD芯片 就可以完成语音识别功能 每次识别最多可以设置50项候选识别句 每个识别句可以是单字 词组或短句 另一方面 识别句内容可以动态编辑修改 只需要主控MCU把识别关
  • 碎碎念,浅浅饮-------Day30

    这不是一篇关乎技术的文章 它偏离了我原本的计划轨迹 但是 相信它的意义会远超出任何一项技术带给我的价值 高考已经开始了 不知道在这片宁静的夜空下有多少人已经美美的睡了 香甜憨然 又有多少人这睡着的眼角还挂着泪滴 偶尔蹙起眉头 却也记载不下那
  • 固态硬盘接口类型介绍

    固态硬盘接口类型介绍 现在装机硬盘肯定会首选SSD 容量小一点不怕 后面再补一个机械硬盘不迟 SSD有着稳固和高速的优势 深受用户喜爱 然而SSD有着各种各样的尺寸和接口 并不是每一个用户的电脑都能通用 所以选购SSD硬盘前必须先了解SSD
  • ajax请求出现闪屏,jquery $.Ajax 火狐浏览器闪屏解决办法

    本文章介绍了关于jquery的async false Ajax 火狐浏览器闪屏解决办法 jquery的async false 这个属性 默认是true 异步 false 同步 代码如下 复制代码 ajax type post url pat
  • vue2知识点梳理

    Vue梳理 对于Vue 我们并不陌生 现在我们来梳理一下关于它的东西吧 知识点 1 生命周期 最基本的就是它的生命周期 beforeCreate 在 beforeCreate 生命周期函数执行时 data 和 methods 中的数据都还没
  • Open3D (C++) 点云按坐标值大小进行排序

    目录 一 概述 二 点云排序 三 结果展示 一 概述 如题 点云按坐标大小进行排序 二 点云排序 代码以按照Z坐标的大小按照从小到大进行排序为例 include
  • java输出1~100之间的全部素数的5种方法

    文章目录 一 前言 二 需求分析 2 1 什么是素数 2 2 分析 三 代码实现 3 1 方法一 根据素数的定义来遍历检查 3 2 方法二 根据判断条件2进行遍历检查 减少遍历次数 3 3 方法三 根据判断条件3进行遍历检查 减少遍历次数