Java实现质数筛的三种方法

2023-11-13

今天在做一个算法题的时候遇到一个需要求质数的情况,但是本人比较菜只会暴力做法,所以在此记录学习一下质数筛选除了暴力以外的其它做法!

注意:一个大于1的自然数,除了1和它自身外,不能被其他自然数整除的数叫做质数

题目

在这里插入图片描述

暴力做法

直接根据定义写一个检测这个数是不是质数的方法,明显超时了

class Solution {
    public int countPrimes(int n) {
        int res = 0;
        for(int i = 1;i < n;i++){
            res = res + isPrime(i);
        }
        return res;
    }

    //验证一个数是不是素数
    public int isPrime(int num){
        if(num <= 1) return 0;
        for(int i = 2;i < num;i++){
            if(num%i == 0) return 0;
        }
        return 1;
    }
}

上面这个还可以优化一下,因为并不需要isPrime判断到num-1,其实到sqrt(num)就行了,但是还是超时,这里判断还可以使用 i * i <= num 来判断,但是在有的题里面可能会溢出 i*i,所以就可以使用i <= num/i来判断,这三种都可以使用,看个人喜好了吧

class Solution {
    public int countPrimes(int n) {
        int res = 0;
        for(int i = 1;i < n;i++){
            res = res + isPrime(i);
        }
        return res;
    }

    //验证一个数是不是素数
    public int isPrime(int num){
        if(num <= 1) return 0;
        
        for(int i = 2;i <= num/i;i++){
            if(num%i == 0) return 0;
        }
        return 1;
    }
}

普通筛选

Java里面没有Bit数组这种类型所以我使用的是Bitset,普通筛选就是将这个数的2倍、3倍 … 全部筛掉因为这些不止除了1和本身的因子,判断一个数是不是质数就只需要判断在不在Bitset里面即可

import java.util.BitSet;
class Solution {
    public int countPrimes(int n) {
        int res = 0;
        BitSet prime = new BitSet();
        for(int i = 2;i <= n/i;i++){
            if(!prime.get(i)){
                for(int j = 2 * i;j < n && j > 0;j+=i){
                    prime.set(j);
                }
            }
        }
        for(int i = 2;i < n;i++){
            if(!prime.get(i))res++;
        }
        return res;
    }
}

埃氏筛法

埃氏筛法就是将前面j = 2 * i 变成 j = i * i 这里,其它类似

import java.util.BitSet;
class Solution {
    public int countPrimes(int n) {
        int res = 0;
        BitSet prime = new BitSet();
        for(int i = 2;i <= n/i;i++){
            if(!prime.get(i)){
                for(int j = i * i;j < n ;j+=i){
                    prime.set(j);
                }
            }
        }
        for(int i = 2;i < n;i++){
            if(!prime.get(i))res++;
        }
        return res;
    }
}

上面这几种筛法看似可以的 ,但是存在重复筛选的情况,比如 2 * 3 * 5这个数就会被筛很多便,所以就出现了欧拉筛选

欧拉筛选

欧拉筛的原理是什么,欧拉筛是根据这个数的最小质因(只因)数来进行筛的,每个数只会被自身最小质因数来筛选,所以这里面就有两个比较重要的了,是怎么确保只被筛选一次以及如何确保不会被漏筛

如何确保只被筛一次
if(i % prime[j] == 0) break; 这就是被确保只被筛选一次,因为这里如果不break的话,那么接下来就是i * prime[j+1] 这个数而 i % prime[j] = 0,所以i = m * prime[j],所以t = i * prime[j+1] = m * prime[j] * prime[j+1],欧拉筛就是通过最小质因数来筛的而这个数的最小质因数是prime[j] 所以可以退出,在i = m * prime[j+1]时候才会被筛选不然会在后面重复筛

如何确保不会漏筛
首先一个大于1的自然数可以分为质数与合数,质数不用管,因为不会被筛选出去,而一个合数都可以变为由一个最小质因子 p * 一个数 m 得到,而p一定是小于该合数的,所以当运行到i 为这个合数的时候,i这个数已经在前面被筛掉了,因为i 同时也是倍数,所以当i = m的时候,p * m就把 当前i给筛掉了

class Solution {
    int cnt = 0;
    int []isPrime = new int[5000010]; // 1 为合数 0为质数
    int []prime = new int[5000010];
    public int countPrimes(int n) {
        for(int i = 2;i < n;i++){
            if(isPrime[i] == 0){
                prime[++cnt] = i;
            }
            for(int j = 1;j <= cnt && prime[j] * i < n;j++){
                isPrime[i * prime[j]] = 1;
                if(i % prime[j] == 0) break;
            }
        }
        return cnt;
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现质数筛的三种方法 的相关文章

随机推荐

  • 解决httpd: Could not reliably determine the server's fully qualified domain name

    測試系統 mdv2007 service httpd restart 出現下面錯誤 Shutting down httpd OK Starting httpd httpd Could not reliably determine the s
  • 如何测试生成式人工智能(AIGC)

    简介 在人工智能日趋普及的今天 生成式人工智能 AIGC 已经成为不可忽视的一个分支 从自动化生成新闻 编写代码到图像和音频生成 AIGC几乎无处不在 但如何确保这些生成的内容达到预期标准 安全可靠 同时又具有高度的可用性呢 这是一个值得细
  • 使用hyper-V 编译和调试Android13(android-13.0.0_r3)源码

    环境 windows10 hyper V ubuntu20 4 LST 之前写了一篇Andrid9的编译 但是之前是使用的Vmware虚拟机 ubuntu20 4 LST 由于重装系统 Vmware不见了 不想单独装个虚拟机软件 加上现在w
  • matlab读取文件各种方法

    本技术支持指南主要处理 ascii binary and mat files 要得到matlab中可用来读写各种文件格式的完全函数列表 可以键入以下命令 help iofun matlab中有两种文件i o程序 high level and
  • js6语法总结

    Vuex Action的 commit
  • Linux定时任务crontab

    格式要求如下 For details see man 4 crontabs Example of job definition minute 0 59 hour 0 23 day of month 1 31 month 1 12 OR ja
  • IOS 图片转换二进制 二进制转换为图片

    类方法 图片 转换为二进制 NSData Image TransForm Data UIImage image NSData imageData UIImageJPEGRepresentation image 0 5 几乎是按0 5图片大小
  • axure到底好不好学,有哪些技巧

    Axure学习难吗 这个问题一直引起很多朋友的讨论 有的觉得难 有的觉得不难 当然 人不一样 每个人的学习方式也不一样 对学习难度的理解自然也不一样 这个问题自然没有定论 在学习的时候 有很多方法可以帮助我们 有不同的意见 我们需要尽可能多
  • 一份完整的问卷模板_Word制作问卷调查模板表「教你复选框打钩」

    作者易雪龙转自 Word联盟 问卷调查相信大家都有用过吧 就是一些问题 然后下面有几个选项给我们选择 类似这种问卷调查模板 其实用Word也是可以制作出来的 今天 易老师就来教一下大家利用Word来制作一份电子版的调查问卷 效果演示 Wor
  • 模型/视图编程

    模型 视图编程 模型 视图编程 模型 视图 委托 模型 视图编程 Qt中的模型 视图架构用来实现大量的数据存储 处理及显示 MVC Model View Controller 包括了3个组件 模型 Model 是应用对象 用来表示数据 视图
  • Lotus Domino Notes表单,页面,视图,文档,域之间的关系

    1 表单 Form 关系型数据库里的 表设计 关系型数据库中通过表设计来定义这张Table上会有哪些字段 字段的类型以及长度等 然后通过Table来创建符合这个Table定义的记录 Record 通常情况下 Lotus通过表单 Form 来
  • Micropython史上最友好的编辑器,小巧精悍

    Python 因为非常好学 易上手故而广受大众的喜欢 micropython 也因此在物联网单片机领域拥有一席之位 并且 python 有着良好的生态环境 功能亦更加丰富 from machine import Pin p0 Pin 0 P
  • 购物商城---SpringMVC拦截器的使用

    springmvc front xml
  • spring data jpa

    Spring Data是什么 Spring Data是一个用于简化数据库访问 并支持云服务的开源框架 其主要目标是使得对数据的访问变得方便快捷 并支持map reduce框架和云计算数据服务 Spring Data 包含多个子项目 Comm
  • 深度学习中矩阵求导公式整理

    深度学习中矩阵求导公式整理 1 两种布局约定方式 2 矩阵求导的类型 3 标量对标量求导 4 向量对标量求导 5 矩阵对标量求导 6 标量对向量求导 7 向量对向量求导 8 标量对矩阵求导 参考文献 1 两种布局约定方式 布局 Layout
  • 机试算法题-敲击计数器

    题目 设计一个敲击计数器 使它可以统计在过去 5 分钟内被敲击次数 即过去 300 秒 您的系统应该接受一个时间戳参数 timestamp 单位为 秒 并且您可以假定对系统的调用是按时间顺序进行的 即 timestamp 是单调递增的 几次
  • CVPR 2022

    点击下方卡片 关注 CVer 公众号 AI CV重磅干货 第一时间送达 转载自 集智书童 On the Integration of Self Attention and Convolution 论文 https arxiv org abs
  • 回溯算法-----473. 火柴拼正方形&&698. 划分为k个相等的子集

    分享两个回溯算法解决的算法题 和自己以往做这类题目的思路不同 导致这里卡了很久 不得不花几个小时总结一下 火柴拼正方形 首先展示一下自己一开始的回溯算法的解决方式 其实这个也是自己进行了优化之后的 没有优化之前是超时的 public boo
  • 如何导出存储过程、函数、包和触发器的定义语句?如何导出表和索引的创建语句?...

    Oracle中如何导出存储过程 函数 包和触发器的定义语句 如何导出表的结构 如何导出索引的创建语句 QQ群里有人问 如何导出一个用户下的存储过程 麦苗答 方法有多种 可以使用DBMS METADATA GET DDL包 使用PL SQL
  • Java实现质数筛的三种方法

    今天在做一个算法题的时候遇到一个需要求质数的情况 但是本人比较菜只会暴力做法 所以在此记录学习一下质数筛选除了暴力以外的其它做法 注意 一个大于1的自然数 除了1和它自身外 不能被其他自然数整除的数叫做质数 题目 暴力做法 直接根据定义写一