gpt4 book ai didi

java - 埃拉托色尼筛问题 : handling really big numbers

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:18:52 26 4
gpt4 key购买 nike

我正在解决 Sphere 的在线法官 Prime Generator使用埃拉托色尼筛法。

我的代码适用于提供的测试用例。但是..正如问题明确指出的那样:

The input begins with the number t of test cases in a single line (t<=10). In each of the next t lines there are two numbers m and n (1 <= m <= n <= 1000000000, n-m<=100000) separated by a space.

我知道 Integer.parseInt() 方法在处理非常大的数字时会抛出异常,在线判断表明会抛出异常,所以我更改了 的每个案例在我的代码中将 parseInt 更改为 parseLong

嗯,在 Netbeans 6.5 上运行良好,m 和 n 的值很小。

package sphere;

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main{

public static void runEratosthenesSieve(long lowerBound, long upperBound) {

long upperBoundSquareRoot = (long) Math.sqrt(upperBound);

boolean[] isComposite = new boolean[(int)upperBound + 1];

for (int m = 2 /*int m = lowerBound*/; m <= upperBoundSquareRoot; m++) {

if (!isComposite[m]) {

if (m>=lowerBound) {System.out.println(m);}

for (int k = m * m; k <= upperBound; k += m)

isComposite[k] = true;

}

}

for (int m = (int)upperBoundSquareRoot; m <= upperBound; m++)

if (!isComposite[m])

if (m>=lowerBound){ System.out.println(m);}

}

public static void main(String args[]) throws java.lang.Exception{

BufferedReader r = new BufferedReader(new InputStreamReader(System.in));


String l = r.readLine();

int testCases = Integer.parseInt(l);

for (int i =0; i<testCases; i++){
String s =r.readLine();

String []splitted=s.split(" ");


long lowerBound = Long.parseLong (splitted[0]);
long upperBound = Long.parseLong(splitted[1]);

runEratosthenesSieve (lowerBound,upperBound);

System.out.println("");
}
}

}

输入+输出:

run:
2
1 10
2
3
3
5
7

3 5
3
5

BUILD SUCCESSFUL (total time: 11 seconds)

但是 JCreator LE 是这样说的:

2
1 10
Exception in thread "main" java.lang.NumberFormatException: For input string: ""
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:48)
at java.lang.Long.parseLong(Long.java:424)
at java.lang.Long.parseLong(Long.java:461)
at sphere.Main.main(Main.java:51)

Process completed.

这里我没有整数溢出,但为什么 jcreator 会报错呢?

考虑到边界测试用例,该程序也在 Netbeans 上崩溃:

run:
2
999900000 1000000000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at sphere.Main.runEratosthenesSieve(Main.java:13)
at sphere.Main.main(Main.java:55)
Java Result: 1

我如何处理问题陈述中那些巨大的整数?

编辑:根据建议,我更改了 BitSet 的 boolean 数组,但我仍然收到 OutOFMemoryError:

package sphere;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.BitSet;

public class Main{

public static void runEratosthenesSieve(long lowerBound, long upperBound) {

long upperBoundSquareRoot = (long) Math.sqrt(upperBound);

//boolean[] isComposite = new boolean[(int)upperBound + 1];

BitSet isComposite = new BitSet((int)upperBound+1);

for (int m = 2 /*int m = lowerBound*/; m <= upperBoundSquareRoot; m++) {

if (!isComposite.get(m)) {

if (m>=lowerBound) {System.out.println(m);}

for (int k = m * m; k <= upperBound; k += m)

isComposite.set(m);

}

}

for (int m = (int)upperBoundSquareRoot; m <= upperBound; m++)

if (!isComposite.get(m))

if (m>=lowerBound){ System.out.println(m);}

}

public static void main(String args[]) throws java.lang.Exception{

BufferedReader r = new BufferedReader(new InputStreamReader(System.in));


String l = r.readLine();

int testCases = Integer.parseInt(l);

for (int i =0; i<testCases; i++){
String s =r.readLine();

String []splitted=s.split(" ");


long lowerBound = Long.parseLong (splitted[0]);
long upperBound = Long.parseLong(splitted[1]);

runEratosthenesSieve (lowerBound,upperBound);

System.out.println("");
}
}

}

输入-输出:

run:
1
999900000 1000000000
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.util.BitSet.initWords(BitSet.java:144)
at java.util.BitSet.<init>(BitSet.java:139)
at sphere.Main.runEratosthenesSieve(Main.java:16)
at sphere.Main.main(Main.java:58)
Java Result: 1
BUILD SUCCESSFUL (total time: 14 seconds)

最佳答案

这是你的问题:

boolean[] isComposite = new boolean[(int)upperBound + 1];

这将使用大量空间,因为它为每个 boolean 值分配 4 个字节以允许更快的访问。使用 java.lang.BitSet避免这种情况。

最终,您的数字也可能会变得太大而持续太久,您将不得不使用 BigInteger。但到那时,埃拉托色尼筛法可能也不再适用了。

关于java - 埃拉托色尼筛问题 : handling really big numbers,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1077907/

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