我试图解决SPOJ上的PrimeNumber Generator问题。代码总是在SPOJ上给出运行时错误,但在ideone.com中它运行正常。不知道是什么导致了这个问题。我尝试了Scanner
和BufferedReader
来阅读输入。
import java.lang.*;
import java.io.*;
class Main
{
public static void main (String[] args) throws java.lang.Exception
{
BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(r.readLine());
while (t > 0) {
String input = r.readLine();
int N1 = Integer.parseInt(input.split(" ")[0]);
int N2 = Integer.parseInt(input.split(" ")[1]);
boolean isPrime[] = new boolean[N2 + 1];
int count = 0;
int primes[] = new int[N2 + 1];
for (int i = 2; i <= N2; i++) {
isPrime[i] = true;
}
for (int i = 2; i * i <= N2; i++) {
if (isPrime[i]) {
for (int j = 2; i * j <= N2; j++) {
isPrime[i * j] = false;
}
}
}
for (int i = 2; i <= N2; i++) {
if (isPrime[i]) {
primes[count++] = i;
}
}
for (int i = 2; i <= N2; i++) {
isPrime[i] = true;
}
for (int i = 0; i < count; i++) {
int p = primes[i];
int s = N1 / p;
s = s * p;
for (int j = s; j <= N2; j = j + p) {
if (j < N1) {
continue;
}
isPrime[j - N1] = false;
}
}
for (int i = 0; i < count; i++) {
if (primes[i] >= N1 && primes[i] <= N2) {
System.out.println(" " + primes[i]);
}
}
for (int i = 0; i < (N2 - N1 + 1); i++) {
if (isPrime[i] == true && (i + N1) != 1) {
System.out.println(i + N1);
}
}
System.out.println("");
t--;
}
}
}
我提供的样本输入是
2
10 30
50 100
我发现错误在第boolean isPrime[] = new boolean[N2 + 1]
行。 N2无法取值达到1000000000。
有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
您正在使用布尔数组:int primes[] = new int[N2 + 1];
用于您的Eratosthenes筛选。为了节省空间使用比特而不是布尔值,例如bitSet
。为了节省更多的空间,只记录奇数的答案,所有的均匀(除了2)是复合的,所以只要你做出2的特殊安排就可以忽略它们。也许是这样的:
if (num % 2 == 0) { return num == 2; }
靠近isPrime()
方法的开头。这将使所需的存储空间减半。
答案 1 :(得分:0)
看起来你的堆内存耗尽了。 Here您对堆大小如何影响您的实现有更具体的描述。
处理此问题的方法之一是更改堆大小
OrderedArray
但我不确定是否可以在SPOJ上做到这一点。
解决这个问题的其他方法是通过拆分这个巨大的数组来管理堆的使用情况,你要声明并处理较小的数组,但是在处理单个子数组之后,你需要取消引用这个数组并调用System.gc( )。
希望有所帮助:)
答案 2 :(得分:0)
而不是
boolean[] isPrime = new boolean[N2 + 1];
你可以做到
BitSet isPrime = new BitSet(N2 + 1);
if (!isPrime.get(i)) {
isPrime.set(i, true);
}
这是一个巨大的内存减少,但速度较慢。