Java程序实现轮筛法生成指定范围内的素数


寻找给定范围内的素数的简单方法是检查每个数是否为素数。此外,我们需要进行等于给定数字的迭代以检查该数字是否为素数。因此,简单方法非常耗时,我们需要对其进行优化以提高效率。

在本教程中,我们将学习由Sieve给出的轮因子分解和埃拉托斯特尼筛法算法,以有效地找到给定范围内的素数。

问题陈述 - 我们给出了左整数和右整数的值。我们需要实现轮因子分解和埃拉托斯特尼筛法算法来找到给定范围内的素数。

示例

输入

left = 10;  right = 50;

输出

11 13 17 19 23 29 31 37 41 43 47

解释

It prints the prime numbers between 10 and 50.

输入

left = 9;  right = 10;

输出

“”

解释

It prints an empty string as there is no prime numbers between 9 and 10.

输入

left = 144; right = 200;

输出

149 151 157 163 167 173 179 181 191 193 197 199

方法1

在这种方法中,我们将使用埃拉托斯特尼筛法算法来查找两个给定数字之间的素数。

在埃拉托斯特尼筛法算法中,我们使用长度为N的数组来根据数字是否为素数来存储布尔值。我们将偶数存储为false,因为它们是非素数。之后,我们访问每个未标记的数字,并将它的倍数的布尔值从true更改为false。

算法

  • 步骤1 - 定义numbers[]数组以根据数字是否为素数存储布尔值。

  • 步骤2 - 执行createMatrix()函数以查找1到10,000,000之间的素数并更新numbers[]数组。

  • 步骤3 - 从4开始遍历到给定范围。如果索引为偶数,则将numbers[p]初始化为false。否则为true。

  • 步骤4 - 使用循环从3迭代到给定范围。如果number[p]为true,则将该数字的所有倍数标记为false。

  • 步骤5 - 执行getPrimes()函数以获取左值和右值之间的所有素数。

  • 步骤5.1 - 在getPrimes()函数中,遍历给定范围内的数组,如果数组元素为true,则打印索引值。

示例

Open Compiler
import java.io.*; public class Main { // Maximum range static boolean numbers[] = new boolean[1000001]; static void createMatrix() { // max range int range = 1000000; // Initially mark even numbers as non-prime and odd numbers as prime for (int p = 4; p <= range; ++p) { if (p % 2 == 0) numbers[p] = false; else numbers[p] = true; } // Traverse all odd numbers and update if the number is not prime for (int p = 3; p <= Math.sqrt(range); p += 2) { // If the number is prime if (numbers[p] == true) { // Update all multiples of p as non-prime for (int q = p * p; q <= range; q += p) { numbers[q] = false; } } } } static void getPrimes (int left, int right) { System.out.println("Prime numbers in the given range are:"); for (int p = left; p <= right; ++p) { // Printing prime numbers in the range if (numbers[p] == true) { System.out.print(p + " "); } } } public static void main(String[] args) { int left = 10; int right = 50; createMatrix(); // Get prime numbers in the given range getPrimes(left, right); } }

输出

Prime numbers in the given range are:
11 13 15 17 19 21 23 27 29 31 33 37 39 41 43 47

时间复杂度 – O(N*logN),其中O(N)用于遍历数组,O(logN)用于将所有倍数标记为false。

方法2

在这种方法中,我们需要获取素数的基本列表。这里,我们将使用{2, 3, 5}。之后,我们需要在将基本列表的所有素数相乘后决定轮的大小。因此,我们的轮大小将为(2*3*5)30。

在下一步中,我们需要获取1到轮大小的所有素数以构成一个轮。我们将采用{7, 11, 13, 17, 19, 23, 29, 31},因为我们已经在基本列表中包含了2, 3和5。

因此,轮包含一层30个数。在每一层中,我们检查数字是否可以被任何最小整数整除以确保该数字是否为素数。

算法

  • 步骤1 - 将'isNumPrime'初始化为true,假设该数字为素数。

  • 步骤2 - 同样,将primes数组初始化为轮的第一层的素数。

  • 步骤3 - 如果数字小于2,则将'isNumPrime'更新为false。

  • 步骤4 - 如果数字可以被2、3或5整除,则将'isNumPrime'更新为false。

  • 步骤5 - 使用循环从0到sqrt(Number)以30为步长进行迭代,因为轮的每一层包含30个数。

  • 步骤6 - 使用嵌套循环遍历第一层的所有素数。如果第一层的素数大于sqrt(num),则中断嵌套循环。

  • 步骤7 - 否则,如果数字可以被第一层的素数 + p(30的倍数)整除,则将'isNumPrime'更新为false并中断嵌套循环。

  • 步骤8 - 在外循环中,如果'isNumPrime'的值为false,则中断外循环。

  • 步骤9 - 返回'isNumPrime'变量的值。

示例

在这个例子中,我们遍历给定范围内的每个数字,并使用轮因子分解算法检查它是否为素数。

Open Compiler
import java.util.*; public class Main { static boolean checkForPrime(int num) { boolean isNumPrime = true; // Wheel of prime numbers int[] primes = { 7, 11, 13, 17, 19, 23, 29, 31 }; // Base Case if (num < 2) { isNumPrime = false; } if (num % 2 == 0 || num % 3 == 0 || num % 5 == 0) { isNumPrime = false; } // Check in the wheel P is the layer of the wheel for (int p = 0; p < Math.sqrt(num); p += 30) { // Check for the list of Sieve in primes[] for (int pm : primes) { // When the prime number exceeds the square root of the num if (pm > Math.sqrt(num)) { break; } // If num is multiple of pm in the current wheel else { if (num % (pm + p) == 0) { isNumPrime = false; break; } } // When a number is non-prime in the current layer if (!isNumPrime) break; } } return isNumPrime; } public static void main(String args[]) { int left = 10; int right = 50; System.out.println("Prime numbers in the given range are :"); for (int p = left; p <= right; ++p) { if (checkForPrime(p) == true) { System.out.print(p + " "); } } } }

输出

Prime numbers in the given range are:
11 13 17 19 23 29 31 37 41 43 47

时间复杂度 – O(N*N1/2)

空间复杂度 – O(1)

只有当我们需要在一个特定范围内查找素数时才使用埃拉托斯特尼筛法算法,而轮因子分解算法用于查找大范围内的所有素数。

更新于:2023年7月4日

浏览量:183

开启您的职业生涯

完成课程获得认证

开始学习
广告