【问题标题】:Spoj NZEC errorSpoj NZEC 错误
【发布时间】:2014-07-03 15:00:36
【问题描述】:

这是我的素数生成代码:

import java.io.BufferedReader;
import java.io.InputStreamReader;
public class prime_gen
{

public static void gen_prime(long min,long max)
{

   long n=max/2,i=0,j=0;

        boolean[] prime = new boolean[(int) max];        
 if(min==1)
{

System.out.println("2");
System.out.println("3");

}
else
if(min==3)
System.out.println("3");
else
if(min==2)
{
System.out.println("2");
System.out.println("3");
}

        for (i = 1; i < n; i++)
            for (j = i; j <= (n - i) / (2 * i + 1); j++)
                prime[(int) (i + j + 2 * i * j)] = true;


for (i = 2; i < prime.length/2; i++)
        {
              if (!prime[(int)i])
                  {
                        if(2*i+1>min)

              System.out.println((2*i+1)+" ");
       }






}
}

public static void main(String args[]) 
{
try
{
int i=0,T=0;
long[] min,max;
String[] s1=new String[2];
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s=br.readLine();
T=Integer.parseInt(s);
min=new long[T];
max=new long[T];

for(i=0;i<T;i++)
{
s1=br.readLine().split(" ");
min[i]=Integer.parseInt(s1[0]);
max[i]=Integer.parseInt(s1[1]);



}

for(i=0;i<T;i++)
{
gen_prime(min[i],max[i]);
System.out.println();
}
}catch(Exception e)
{
return;

}   }

}

约束是:

T<=10
max<=1000000000
max-min<=100000

我使用 sundaram 的筛子生成素数,代码在我的测试用例中运行良好。我还使用 try catch 块来处理异常。我不知道这段代码有什么问题。spoj 论坛说每当 JVM 产生异常时,都会抛出 NZEC 错误。

【问题讨论】:

    标签: java primes


    【解决方案1】:

    上面的代码适用于较小的输入,但是您检查过您处理的corner or extreme cases 吗?当您使用extreme cases 检查它时,您会发现您的代码为他们提供了runtime error..try它在ideone 上会出现运行时错误。现在这是什么问题?想想我们有输入的单个测试用例

    999900000 1000000000

    现在根据你的代码

    n = max / 2 = 1000000000 / 2 = 500000000
    

    现在直接转到您的for loop

    for (i = 1; i < n; i++)
            for (j = i; j <= (n - i) / (2 * i + 1); j++)
                prime[(int) (i + j + 2 * i * j)] = true;
    

    考虑外部循环的最后一个值(总是考虑极值)

    i = 500000000 (although `i` will be 1 less than this value ,I am considering it for simplicity as it will have not considerable effect and make our calculations easier)
    j = i
    

    现在您为prime 数组处理的索引现在是j 的第一个值

    prime[(int) (i + j + 2 * i * j)] = 500000000 + some positive number
    

    任何编程语言中数组的大小都不是那么大(我不了解 JAVA)..它大约是 10^6 maximum(在 JAVA 中可以更多)..所以你正在访问的索引无法管理..这就是你得到runtime error..你必须改变你的方法..

    现在我要指出的另一件事是Sieve of Sundaram 的复杂性

    O(n * log n)

    Sieve of Eratosthenes 具有复杂性

    O(n * log(log n))

    所以我认为你应该使用Sieve of Eratosthenes,因为Sieve of Sundaram 可能导致TLE..但Sieve of Eratosthenes不仅足够..你必须使用segmented sieve这个问题..可能还有其他方法可以解决这个问题。

    EDIT 1:- 不会超出你已经使用的范围

    boolean[] prime = new boolean[(int) max];
    

    只有在您输入我提到的测试用例后,您才会在上面的行中得到runtime error,因为在coding websites 上不允许创建如此大的数组

    编辑 2:- 我运行了一个简单的代码来查找是否有可能为数组提供这么多内存,但我不这么认为..这是代码

    import java.util.*;
    import java.lang.*;
    import java.io.*;
    
    class Ideone
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            long max = 1000000000;
            boolean[] prime = new boolean[(int) max];
            System.out.println("IT WORKED");
        }
    }
    

    这就是我得到的

    Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at Ideone.main(Main.java:13)
    

    链接to the code..它因10 ^ 9数组大小而失败

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多