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
重写这两个。您也不需要将 0
和 X.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的主要内容,如果未能解决你的问题,请参考以下文章