gpt4 book ai didi

java - 如何在java中生成大量素数?

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:15:19 28 4
gpt4 key购买 nike

为了解决一个问题,我必须生成一个从 1 到 3000000 的素数列表,所以我尝试了几种方法来做到这一点,不幸的是都失败了......

第一次尝试:因为所有大于2的质数都是奇数,所以我先生成一个以3开头的奇数列表,叫做allOddNums。然后我生成一个名为 allComposite 的所有合数列表。然后我从 allOddNums 中删除 allComposite 中的所有数字以获得质数。这是我的代码:

/** Prime Numbers Generation
* Tony
*/
import java.util.*;

public class PrimeNumG {
public static void main(String[] args) {

List <Long> allOddNums = new ArrayList<Long>();
for (long i = 3; i < 200; i += 2) {
allOddNums.add(i);
}

// composite number generator:
List <Long> allComposite = new ArrayList<Long>();
for (long a = 2; a < Math.round(Math.sqrt(3000000)); a += 2) {
for (long b = 2; b < Math.round(Math.sqrt(3000000)); b += 2) {
allComposite.add(a*b);
}
}

// remove duplicated:
Set <Long> hs = new HashSet<Long>();
hs.addAll(allComposite);
allComposite.clear();
allComposite.addAll(hs);

// remove all composite from allRealNums = allPrime
allOddNums.removeAll(allComposite);
allOddNums.add(0, (long)2);

System.out.printf("%s ", allOddNums);
Scanner sc = new Scanner(System.in);
int times = sc.nextInt();

for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(allOddNums.get(index) + " ");

}
}
}

在这种情况下,当我需要生成一些质数时,它工作正常。但是,如果我想生成直到 3000000,它就会失败(耗尽内存)。

第二次尝试:我在网上搜索并找到了一种名为埃拉托色尼筛法的算法。然后我首先生成 2, 3, 5, 7, 9...(所有奇数 + 2),然后我删除 3 之后的每个第 3 个数字和 5 之后的每个第 5 个数字。代码如下:

/** Prime Number Generator
* Tony
*/
import java.util.*;

public class Solution61 {
public static void main(String[] args) {
List<Long> l1 = new ArrayList<Long> ();

// l1 generator: 3 5 7 9 11 ...
for (long d = 3; d < 100; d += 2) {
l1.add(d);
}

l1.add(1, (long)2); // 2 3 5 ...

removeThird(l1); // rm 3rd after 3

removeFifth(l1); // rm 5th after 5, now the l1 will be prime number

Scanner sc = new Scanner(System.in);
int times = sc.nextInt();
for (int i = 0; i < times; i++) {
int index = sc.nextInt();
System.out.print(l1.get(index) + " ");


}
}


/** removeThird : remove every 3rd number after 3
* param List | return void
*/
private static void removeThird(List<Long> l) {

int i = 1;
int count = 0;
while (true) {


if (count == 3) {
l.remove(i);
count = 1;

}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}

/** removeThird : remove every 5th number after 5
* param List | return void
*/
private static void removeFifth(List<Long> l) {

int i = 2;
int count = 0;
while (true) {


if (count == 5) {
l.remove(i);
count = 1;
}
i ++;
count ++;
if (i > l.size()) {
break;
}
}
}

}

这仍然不能完成任务,因为它也耗尽了内存。

第三次尝试:我试着生成从 1 到 3000000,然后去掉每一个数是质数和另一个数的乘积。代码如下:

/** print all the prime numbers less than N
* Tony
*/

public class primeGenerator {
public static void main(String[] args) {
int n = 3000000;
boolean[] isPrime = new boolean[n];
isPrime[0] = false; // because 1 is not a prime number

for (int i = 1; i < n; i++) {
isPrime[i] = true;
} // we set 2,3,4,5,6...to true

// the real number is always (the index of boolean + 1)

for (int i = 2; i <= n; i++) {
if (isPrime[i-1]) {
System.out.println(i);
for (int j = i * i; j < n; j += i /* because j is determined by i, so the third parameter doesn't mater*/) {
isPrime[j-1] = false;
}
}
}
}
}

它仍然让我失望,我猜 3000000 真的是一个很大的数字吧?是否有任何简单而出色的新手友好方法来生成 3000000 以下的素数?谢谢!

第四次尝试:@jsheeran 下面的代码是您的答案的意思吗?当我达到 1093 时,它变得越来越慢,我的 IDE 仍然崩溃。如果我误解了你的方法,请告诉我,谢谢!

/** new approach to find prime numbers
* Tony
*/
import java.util.*;

public class PrimeG {

/** isPrime
* To determine whether a number is prime by dividing the candidate number by each prime in that list
*/
static List<Long> primes = new ArrayList<Long> ();

private static void isPrime(long n) {
boolean condition = true;
for (int i = 0; i < primes.size(); i++) {
if (n % primes.get(i) == 0) {
condition = condition && false;
}
}
if (condition) {
findNextPrime(n);
}
}

/** findNextPrime
* expand the list of prime numbers
*/
private static void findNextPrime(long n) {
primes.add(n);
}





public static void main(String[] args) {
primes.add((long)2);
primes.add((long)3);
primes.add((long)5);
primes.add((long)7);

for (int i = 8; i < 3000000; i++) {
isPrime(i);
System.out.printf("%s", primes);
}


}
}

最佳答案

修复了埃拉托色尼筛法的实现(您的第三次尝试)。我相信它应该能满足您的需求。

public static void main (String[] args) throws java.lang.Exception {
int n = 3000000;

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

for (int factor = 2; factor*factor <= n; factor++) {
if (isPrime[factor]) {
for (int j = factor; factor*j <= n; j++) {
isPrime[factor*j] = false;
}
}
}

for (int i = 2; i <= n; i++) {
if (isPrime[i]) System.out.println(i);
}
}

关于java - 如何在java中生成大量素数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39655817/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com