快速高效求素数|质数的方法—Java(模板)

判断素数|质数方法时间效率:线性筛法>埃氏筛法>试除法

在写算法题的时候,各种各样跟素数有关的题目非常常见,本文列出了三种常见的判断素数的方法

三种求素数方法的优缺点

一、试除法

试除法的基本思想是:判断一个数 x 是否为素数,需要检查从 2 到 sqrt(x)(即 x/i)之间的所有数。如果存在一个数 i 能整除 x,则 x 不是素数。我们只需要检查到 sqrt(x),因为如果 x = a * b,那么必定存在一个 a <= sqrt(x) 和一个 b >= sqrt(x),因此我们只需要检查较小的因子。

注意:sqrt()方法的计算速度较慢,并且为了防止溢出的问题,建议写成i<=x/i

java 复制代码
 static boolean get(int x){
      if(x<2)return false;
      for(int i=2;i<=x/i;i++){
          if(x%i==0)return false;
      }
      return true;
 }

二、埃氏筛法

埃氏筛法:

假设所有数都为素数,从 2 开始。

对于每个素数 i,将其所有的倍数标记为合数(即不是素数)。

继续处理下一个未标记的数作为素数,直到遍历到 x。

最终,未被标记的数即为素数。

数据量大于10e7可能会超时

java 复制代码
    static void get(int x){
        for(int i=2;i<=x;i++){
            if(!flag[i]){
                pri[cnt++]=i;
                for(int j=i+i;j<=x;j+=i)flag[j]=true;
            }
        }
    }

三、线性筛法

线性筛法是在埃氏筛法的基础上进行优化。

区别:

埃氏筛法:每次遍历素数时都需要标记所有倍数为合数。

线性筛法:只标记 i 与当前已有的素数相乘的倍数(不再处理重复倍数)。这样可以避免多次重复标记,提高效率。

筛法过程:

遍历每个数 i,如果 i 是素数(即 flag[i] == false),则将其加入素数列表。

对于每个素数 p,从 i * p 开始标记合数,直到 x。

注意标记时,若 i 已经被 p(一个较小的素数)整除,则不再继续与更大的素数进行标记,避免重复。

java 复制代码
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.List;

public class Main {
    static int N=1000010;
    static List<Integer> list=new ArrayList<>();
    static boolean flag[]=new boolean[N];
    public static void main(String[] args) throws IOException {
        Read sc=new Read();
        int n=sc.nextInt();
        get(n);
        System.out.println(list.size());
    }
    static void get(int n){
        for(int i=2;i<=n;i++){
            if(!flag[i])list.add(i);
            for(int j=0;list.get(j)<=n/i;j++){
                flag[list.get(j)*i]=true;
                if(i%list.get(j)==0)break;
            }
        }
    }
}

class Read{
    StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
    public int nextInt() throws IOException {
        st.nextToken();
        return (int)st.nval;
    }
}
相关推荐
与遨游于天地5 分钟前
Spring解决循环依赖实际就是用了个递归
java·后端·spring
陈果然DeepVersion9 分钟前
Java大厂面试真题:Spring Boot+微服务+AI智能客服三轮技术拷问实录(六)
java·spring boot·redis·微服务·面试题·rag·ai智能客服
星星火柴93623 分钟前
笔记 | C++面向对象高级开发
开发语言·c++·笔记·学习
Coovally AI模型快速验证30 分钟前
当视觉语言模型接收到相互矛盾的信息时,它会相信哪个信号?
人工智能·深度学习·算法·机器学习·目标跟踪·语言模型
码界奇点30 分钟前
Rust 性能优化全流程从 flamegraph 定位瓶颈到 unsafe 与 SIMD 加速响应快
开发语言·性能优化·rust·simulated annealing
BeingACoder32 分钟前
【SAA】SpringAI Alibaba学习笔记(一):SSE与WS的区别以及如何注入多个AI模型
java·笔记·学习·saa·springai
DolphinScheduler社区33 分钟前
真实迁移案例:从 Azkaban 到 DolphinScheduler 的选型与实践
java·大数据·开源·任务调度·azkaban·海豚调度·迁移案例
电院工程师1 小时前
SIMON64/128算法Verilog流水线实现(附Python实现)
python·嵌入式硬件·算法·密码学
轮到我狗叫了1 小时前
力扣.84柱状图中最大矩形 力扣.134加油站牛客.abb(hard 动态规划+哈希表)牛客.哈夫曼编码
算法·leetcode·职场和发展
丛雨要玩游戏1 小时前
字符函数和字符串函数
c语言·开发语言·算法