2 Java 方法 java.lang.NullPointerException

Posted

技术标签:

【中文标题】2 Java 方法 java.lang.NullPointerException【英文标题】:2 Java methods java.lang.NullPointerException 【发布时间】:2011-02-26 19:57:03 【问题描述】:

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

算法:

    如果 n ≤ 3 通过蛮力找到最近的点并停止。 找到一条垂直线 V,以便将输入集分成大小尽可能相等的两个不相交的子集 PL 和 PR。左边或线上的点属于 PL,右边或线上的点属于 PR。由于集合是不相交的,因此没有任何点属于两者。 递归地找到 PL 中最近的一对点的距离 δL 和最近的一对点的距离 δR 在 PR 中配对。 令 δ = min(δL, δR)。输入集 P 中一对最近点的距离或者是在递归步骤中找到的点的距离(即 δ),或者由 PL 中的一个点和 PR 中的一个点之间的距离组成。
      只有一个来自 PL 和一个来自 PR 的候选点必须在一个垂直条中,包括 线 V 左侧距离 δ 的线和 V 右侧距离 δ 的线 令 YV 为条带内的点数组,按非递减 y 坐标排序 (即,如果 i ≤ j 则 YV [i] ≤ YV [j])。 从 YV 中的第一个点开始,并通过除最后一个点之外的所有点,检查该点与接下来的 7 个点的距离(如果少于 7 个,则检查剩下的任何点)。如果发现一对距离严格小于 δ,则将此距离分配给 δ。
    返回 δ。

底线是,它使用概念扫描线和递归来找到欧几里得空间中的最近点。

现在我要写的方法:

public static int cP(pointSet P).

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

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

其他方法和类

平面中的点由Point 类的对象表示。这很明显;它将 x 和 y 坐标保存为数字,因此如果 P 是 Point 类型的对象,则 P.x 和 P.y

输入点的集合由 PointSet 类的对象表示。因为这是 一个集合不能有一个点的重复,我们不能假设元素有任何顺序。

public static PointSet gP(String f).

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

public Point nP(PointSet P).

这是用来对P中的点进行迭代。算法closestPair由方法实现

公共静态点最接近对(PointSet P)。

    如果 n = 2 则返回 (x1 - x2)^2 + (y1 - y2)^2 其他 d ← 0 for i ← 1 to n − 1 do   对于 j ← i + 1 到 n 做      t ← (xi − xj)^2 + (yi − yj)^2      如果 t       d ← t 返回 d

public static PointSet generatePoints(int n).

这会返回一组 n 个点,其坐标是整数。

public Point[] sort(char c).

这将返回数组中点集中的点,该数组按参数 c 指示的坐标按非递减顺序排序。此参数采用值“x”或值“y”,否则将引发异常 UnknownSortOptionException。

这是我到目前为止写的:

我决定第一个方法应该做琐碎的情况,n=

  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);

//生成 t 组大小为 n 的点,并获得声称的最近点的平方距离 使用您对每个集合的方法最接近对的实现进行配对。如果所有结果 是正确的,则返回一条报告此问题的消息,否则报告失败。没有进一步的 给出了信息。请注意,t 必须严格为正(一个例外 Invalid- 否则会引发 NumberOfTestsException)。

当我给出可变距离值时,我在线程“main”java.lang.NullPointerException 中的 3 个位置出现以下异常(我在上面记下了)...我该怎么办?

【问题讨论】:

这是作业吗?如果是这样,请标记它。 这与***.com/questions/5109942/runtime-explanation有关 不是真的...运行时与此无关 我为您的问题添加了一些格式,这可能有助于理解它。还有一些不清楚的地方,你应该再看一遍:你只需要找到最小距离,还是你也想自己得到对? 哎呀,@Paulo,我也是。很抱歉,我没有收到关于您的编辑的警告。 【参考方案1】:

好的,让我们看看您的代码。首先,一个小提示:要在 ***(和其他 stackexchange 站点)上发布代码,最好只使用空格进行缩进,因为选项卡看起来很糟糕。

所以,这里你的代码再次正确缩进(通过 Emacs 与 JDEE 的方式 - 看起来我没有正确配置它,或者它在弄清楚你的代码时遇到了一些问题),并且我的 cmets 散布在其中。

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-array 中收集那些靠近分隔线的元素。

    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]));
            
        

d和之前的distance一样吗?

    return d;

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

【讨论】:

@Patrick88:恭喜你的程序到目前为止。 (我现在要睡觉了,但如果现在需要更多,也许其他人可以提供帮助。) 当我定义一个类 Test 并使用生成方法来测试 bove 方法时,我得到 nullPointerException 的距离......任何想法为什么? 打印堆栈跟踪,它应该显示行号。看看这条线。 它现在只在距离变量中,也放在提供的代码中,因为该代码是正确的,所以没有任何意义

以上是关于2 Java 方法 java.lang.NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

使用 PlainUsername 的空指针异常

Lollipop 设备的共享元素转换崩溃

java方法参数

从零开始的Java开发1-2-4 Java方法

Java高级教程

Java高级教程