2 Java方法java.lang.NullPointerException

时间:2011-02-26 19:57:03

标签: java algorithm

我在以下代码中收到错误java.lang.NullPointerException错误。

算法:

  1. 如果n≤3通过蛮力找到最近的点并停止。
  2. 找到垂直线V,使得将输入集分成两个不相交的子集PL和PR,其大小尽可能相等。左侧或线上的点属于PL并指向右侧或线上属于PR。没有一点属于两者,因为这些集是不相交的。
  3. 递归地求出PL中最近点对的距离δL和最近点的距离δR 在公关中配对。
  4. 设δ= min(δL,δR)。输入集P中的一对最近点的距离是在递归步骤中找到的点的距离(即,δ),或者由PL中的点与PR中的点之间的距离组成。
    1. PL的唯一候选点和PR的一个候选点必须在垂直条带中 线V的左边的距离δ处的线和V的右边的距离δ处的线
    2. 设YV是条带内的点的数组,按非递减y坐标排序 (即,如果i≤j则YV [i]≤YV[j])。
    3. 从YV中的第一个点开始,然后踩到除最后一个之外的所有点,检查此点与接下来的7个点的距离(如果没有多达7个点,则检查剩余的点)。如果发现一对距离严格小于δ,则将该距离指定为δ。
  5. 返回δ。
  6. 底线是,它使用概念扫描线和递归来查找欧几里得空间中最近的点。

    现在我要写的方法是:

    • public static int cP(pointSet P).

      这确实为算法的递归部分做了准备工作,并为递归部分调用了nearestPairAux方法。

    • public static int cPA(Point [] X, Point [] Y). 该方法执行算法的递归部分;也就是说,大部分工作。

    其他方法和类

    点在Point中由Point类的对象表示。这是显而易见的事情;它将x和y坐标保持为数字,这样如果P是Point类型的对象,那么P.x和P.y

    输入点集由PointSet类的对象表示。就是这样 一个集合不能重复一个点,我们不能对元素进行任何排序。

    • public static PointSet gP(String f).

      这将打开一个名为f的文件,并从中读取点。

    • public Point nP(PointSet P).

      这用于迭代P中的点。算法closestPair由方法实现

    • public static Point nearestPair(PointSet P)。

      1. 如果n = 2则返回(x1 - x2)^ 2 +(y1 - y2)^ 2
      2. 否则
      3. d←0
      4. for i←1 to n - 1 do
      5. for j←i + 1 to n do
      6. t←(xi-xj)^ 2 +(yi-yj)^ 2
      7. 如果t<那么
      8. d←t
      9. return d
    • public static PointSet generatePoints(int n).

      返回一组n个点,其坐标为整数。

    • public Point[] sort(char c).

      这将返回数组中设置的点中的点,这些点以非递减顺序按坐标排序,如参数c所示。此参数采用值'x'或值'y',否则引发异常UnknownSortOptionException。

    这是我到目前为止写的:

    我决定第一种方法应该做的是小事,n =< 3,然后调用aux方法。

      public static int cP(PointSet P) 
            throws TrivialClosestPairException, UnknownSortOptionException
    {
               int distance = 0;// a method form the Poirnt class that calculate the square                              distance between this point and another point
               Point[] x = P.sort('x');
        Point[] x = P.sort('y');
    
            distance = cPA(x, y); **->here**
    
        return distance;
    
    }
    

    是否应该定义此方法?

    第二个:我需要大量时间帮助这个。

    public static int cPA(Point[] X, Point[] Y) 
            throws TrivialClosestPairException, UnknownSortOptionException
    {
        if (X.length<4){
             return PointSet.nCP(new PointSet (X));
    
     }
    
        int V = X[(int) Math.ceil(( (double) X.length/2)-1)].getX();
    
    
        Point[] PL = Arrays.copyOfRange(X,(int) 0,(int) Math.ceil(X.length/2));
        Point[] PR = Arrays.copyOfRange(X,(int) Math.floor(X.length/2), (int) X.length-1);
    
    
         int distance = Math.min(cPA(PL,Y),cPAPR,Y));**->here**
    
        Point[] shortDist = new Point[Y.length];
    
    
           int n = 0;
    
    
         for (int i = 0; i <Y.length; i++)
    {
    
         int A = Y[i].getY();
          if ((V-A)*(V-A) <= distance)
      {
    
       shortDist[n] = Y[i];
    
           }
        }
    
    
        for (int i =0; i< shortDist.length -1; i++)
       {
    
    
      for (int r = i+1; r <shortDist.length-1 && r< i + 7; r ++){
         distance = Math.min(d, shortDist[i].sqrDist(shortDist[r]));**->here**
    
     }
      }
    
     return distance;**->here**
    
     }
    

    现在我定义以下类来测试我的方法

         public class Test{
    public static void main(String [ ] args)
     {
       ClosestPair.closestPairCheck( 10, 10);
    

    //生成大小为n的t组点,并获得声称最近的点的平方距离    使用您对每个set的方法nearestPair的实现配对。如果全部结果    如果正确,则返回报告此消息的消息,否则报告失败。没有进一步的    给出了信息。请注意,t必须严格为正(异常无效 - 否则会引发NumberOfTestsException)。      }     }

    当我给出变量距离值时,我在3个点的线程“main”java.lang.NullPointerException中得到以下异常(我在上面注意到了)......我该怎么办?

1 个答案:

答案 0 :(得分:3)

好的,让我们来看看你的代码。首先,一个小提示:对于要在stackoverflow(和其他stackexchange站点)上发布的代码,最好只使用空格进行缩进,因为制表符看起来很糟糕。

所以,在这里你的代码再次正确缩进(就像Emacs与JDEE一样 - 看起来我没有正确配置它,或者它有一些问题找出你的代码),并且我的评论穿插了。 / p>

public static int closestPairAux(Point[] X, Point[] Y) 

那么,问题又是:这两个参数数组的含义是什么?它们是否包含相同的点或其他点?你为什么给两个阵列?当你回答这个问题后,给他们更好的名字。

除此之外,请为您的方法提供文档注释。它收到了什么参数,它返回了什么? (如果我理解的话,它不会返回距离,而是距离的平方。)

    throws TrivialClosestPairException, UnknownSortOptionException
{
    if (X.length<4){
        return PointSet.naiveClosestPair(new PointSet (X));
    }

好的,这里有小数组的递归结束。

    int V = X[(int) Math.ceil(( (double) X.length/2)-1)].getX();

如果我理解正确,你试图在这里得到数组的中间元素。这种方式会更清楚:

int middleIndex = X.length/2;
int V = X[middleIndex].getX();

在Java中,整数除法通过舍入为零来工作 - 因此长度为20或21的数组的middleIndex都是10.(如果在第一种情况下希望它为9,则减去1分开之前。)

当然您可以将其写为int V = X[X.length/2].getX();,但您可以在接下来的两个语句中再次使用middleIndex

    Point[] PL = Arrays.copyOfRange(X,(int) 0,(int) Math.ceil(X.length/2));
    Point[] PR = Arrays.copyOfRange(X,(int) Math.floor(X.length/2), (int) X.length-1);

如上所述,像以前一样使用middleIndex重写这两个。您也不需要将0X.length-1转换为int,它们已经是。 (再看一下Arrays.copyOfRange的文档 - to索引是独占的。)

所以,在这里你将X阵列分成两个(大约)相同大小的数组,好吧。

    int distance = Math.min(closestPairAux(PL,Y),closestPairAux(PR,Y));

这是你的递归电话。你到底在做什么呢?为什么要将这些参数提供给递归调用? (特别是,为什么两者都接收相同的Y数组?

    Point[] shortDist = new Point[Y.length];

    int n = 0;
    for (int i = 0; i <Y.length; i++)
        {
            int A = Y[i].getX();
            if ((V-A)*(V-A) <= distance)
                {
                    shortDist[n] = Y[i];
                }
        }

所以,现在你要浏览你的Y数组,收集新shortDist - 数组中分隔符附近的那些元素。

    for (int i =0; i< shortDist.length -1; i++)
        {
            for (int r = i+1; r <shortDist.length-1 && r< i + 7; r ++){
                d = Math.min(d, shortDist[i].sqrDist(shortDist[r]));
            }
        }

之前ddistance相同吗?

    return d;
}

总之,它看起来像是算法的实现,是的。想一想我的问题,请至少在代码上运行一个编译器,以确保它没有明显的语法错误(通过拼写错误)。 在代码中的正确位置(代码块之前)添加注释,并针对某些(可能是随机的)示例输入测试算法,将其与 naive 实现进行比较(它们应该返回相同的结果,但你的希望更快。)