学习记录:Java的素数筛算法

该文章详细描述了一种名为埃拉托斯特尼筛法的算法,用于寻找小于等于给定整数n的所有素数。通过初始化布尔数组和两个嵌套循环,文章解释了如何标记合数并仅保留素数。
摘要由CSDN通过智能技术生成

函数接受一个整数n作为参数,并返回一个小于等于n的所有素数的数组。

import java.util.Arrays;  
  
  
    public static int[] sieveOfEratosthenes(int n) {  
        boolean[] isPrime = new boolean[n + 1];  
        for (int i = 2; i <= n; i++) {  
            isPrime[i] = true;  
        }  
  
        int[] primes = new int[n];  
        int count = 0;  
  
        for (int i = 2; i <= n; i++) {  
            if (isPrime[i]) {  
                primes[count++] = i;  
            }  
            for (int j = 0; j < count && i * primes[j] <= n; j++) {  
                isPrime[i * primes[j]] = false;  
                if (i % primes[j] == 0) {  
                    break;  
                }  
            }  
        }  
  
        return Arrays.copyOf(primes, count);  
    }  
  

初始化isPrime数组

  boolean[] isPrime = new boolean[n + 1];  
    for (int i = 2; i <= n; i++) {  
        isPrime[i] = true;  
    } 

        我们将所有数初始化为素数(isPrime[i] = true),因为一开始我们假设所有数都是素数,然后通过后续的筛选过程将非素数标记为false

初始化primes数组

        int[] primes = new int[n];  
        int count = 0;  

        创建一个数组primes,用于存储找到的素数,(数组的大小为n,但实际上我们可能并不需要存储所有的n个数,因为素数在总数中只占一小部分,但为了简化代码,我们先这样初始化  )
        count用于记录到目前为止找到的素数个数  

双循环部分

for (int i = 2; i <= n; i++) {  
            if (isPrime[i]) {  
                primes[count++] = i;  
            }  
            for (int j = 0; j < count && i * primes[j] <= n; j++) {  
                isPrime[i * primes[j]] = false;  
                if (i % primes[j] == 0) {  
                    break;  
                }  
            }  
        }  
  

外循环 for (int i = 2; i <= n; i++) 遍历从2到n的所有整数。对于每个整数i,我们检查它是否是素数,并用它来筛去合数。

内循环 for (int j = 0; j < count && i * primes[j] <= n; j++) 是一个嵌套的循环,用于筛去合数。这个循环使用已经找到的素数(存储在primes数组中)来标记合数。

  1. 外循环的作用
    • 对于每个整数i,首先检查isPrime[i]是否为true。如果是,说明i是一个素数,我们将其添加到primes数组中,并增加count的值。
    • 接下来,内循环开始执行,使用i和已经找到的素数来筛去合数。
  2. 内循环的作用
    • primes[j]是已经找到的素数,我们用它来检查i * primes[j]是否是合数。如果是,我们将isPrime[i * primes[j]]设为false,标记它为一个非素数。
    • 内循环会继续执行,直到满足以下任一条件:
      • j达到count的值,即已经用所有已知的素数筛过i了。
      • i * primes[j]大于n,即不再需要筛更大的数了。
    • 内循环中有一个重要的优化:如果i能被primes[j]整除(即i % primes[j] == 0),那么i一定不是素数(因为除了1和它本身以外,它还有其他的因数)。在这种情况下,iprimes[j+1]primes[j+2]等的乘积都已经在之前的循环中被primes[j]筛过了,因此无需再次筛除。通过break语句跳出内循环,可以节省不必要的计算。

通过这个双循环,可以有效地找到小于等于n的所有素数,并将它们存储在primes数组中。最后,使用Arrays.copyOf方法返回包含实际素数个数的数组。

这个算法的关键在于利用已经找到的素数来高效地筛去合数,避免了不必要的重复计算,从而提高了算法的效率。

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值