[英]java stackoverflow error
大家好,我正在为一个大学课程开发程序,该程序使用一种称为get_line()的方法来递归计算从网格上的一个点到另一个点的连续位置列表。 当我运行它时,在该方法中最后一个return语句的行上出现堆栈溢出。 我想知道是否可以让其他人查看该方法,看看是否有什么看起来完全错误。 该方法提供如下:
感谢您的帮助!
location是包含行r和列c的对象。
private Vector<location> get_line(location from, location to) {
location nextLoc = new location();
Vector<location> loc = new Vector<location>();
Random r = new Random();
if(to.r == from.r && to.c == from.c) {
return(loc);
} else {
if(to.r > from.r && to.c > from.c) {
nextLoc.r = from.r + 1;
nextLoc.c = from.c + 1;
} else if(to.r < from.r && to.c < from.c) {
nextLoc.r = from.r - 1;
nextLoc.c = from.c - 1;
} else if(to.r < from.r && to.c > from.c) {
nextLoc.r = from.r - 1;
nextLoc.c = from.c + 1;
} else if(to.r > from.r && to.c < from.c) {
nextLoc.r = from.r + 1;
nextLoc.c = from.c - 1;
} else if(to.r == from.r && to.c > from.c) {
if(r.nextInt(2) == 0) {
nextLoc.r = from.r + 1;
} else {
nextLoc.r = from.r - 1;
}
nextLoc.c = from.c + 1;
} else if(to.r == from.r && to.c < from.c) {
if(r.nextInt(2) == 0) {
nextLoc.r = from.r + 1;
} else {
nextLoc.r = from.r - 1;
}
nextLoc.c = from.c - 1;
} else if(to.r < from.r && to.c == from.c) {
nextLoc.r = from.r - 1;
if(r.nextInt(2) == 0) {
nextLoc.c = from.c + 1;
} else {
nextLoc.c = from.c - 1;
}
} else if(to.r > from.r && to.c == from.c) {
nextLoc.r = from.r + 1;
if(r.nextInt(2) == 0) {
nextLoc.c = from.c + 1;
} else {
nextLoc.c = from.c - 1;
}
}
loc.add(nextLoc);
return(get_line(nextLoc,to)); //stack overflow error occurs here.
}
}
这两个参数为真的条件是:
if(to.r == from.r && to.c == from.c)
在我的浏览过程中,似乎总是对nextloc
进行了修改,因此上述声明永远不会成立。
“ to.r == from.r && to.c == from.c”永远不会评估为真...
如果堆栈溢出,则可能存在无限循环。 换句话说,您的算法永远找不到“到”点。 尝试在方法开始时打印出“ nextLoc”值,以查看它是否在匹配方面取得了进展。 然后,您可以尝试找出算法出了问题的地方。
您在这里有一个递归函数。 那是一个自我调用的函数。 每次进行方法调用时,都会向堆栈中添加一个框架。 如果递归函数没有在合理数量的递归中退出,则将耗尽堆栈空间。 因此堆栈溢出。 正如其他人所说,您的条件之一似乎总是错误的,因此您将无限递归(直到耗尽堆栈空间)。 这就像一个无限循环,只是硬件无法处理它,因此它崩溃了,而不是永远工作。
通过-Xss
http://forums.sun.com/thread.jspa?threadID=756468增加运行时堆栈大小
如果您简化代码,则可能会更容易看到该问题,因为其中包含不必要的重复。 您的行和列操作可以是独立的
if ( to.r > from.r ){
nextLoc.r = from.r + 1;
} else if ( to.r < from.r) {
nextLoc.r = from.r -1;
}
if ( to.c > from.c ){
nextLoc.c = from.c + 1;
} else if ( to.c < from.c) {
nextLoc.c = from.c -1;
}
与同等学历相比,我发现更容易理解:
if(to.r > from.r && to.c > from.c) {
nextLoc.r = from.r + 1;
nextLoc.c = from.c + 1;
} else if(to.r < from.r && to.c < from.c) {
nextLoc.r = from.r - 1;
nextLoc.c = from.c - 1;
} else if(to.r < from.r && to.c > from.c) {
nextLoc.r = from.r - 1;
nextLoc.c = from.c + 1;
} else if(to.r > from.r && to.c < from.c) {
nextLoc.r = from.r + 1;
nextLoc.c = from.c - 1;
首先,每次输入方法时,您都在为随机数生成器植入种子,移动:
Random r = new Random();
到类的属性。
其次,如果您的方法返回,则它只会返回一个空的Vector,因为您每次都会创建一个新的Vector。
第三,您列举了8个可能的方向,这些方向使代码比所需的更加复杂,请尝试分别处理行和列来重写它,例如:
if (to.c == from.c && to.r == from.r) {
// reached destination
return;
}
if (to.c > from.c) {
// move right
} else if (to.c < from.c) {
// move left
} else {
// random step left/right
}
if (to.r > from.r) {
// move down
} else if (to.r < from.r) {
// move up
} else {
// random step up/down
}
// take next step
编辑 :你的算法,因为它现在只能达到to
的位置,如果最后一步是对角线。 如果最后一步是水平的,则始终会垂直转向,反之亦然,因此,您将无限地徘徊在目标广告周围,从而导致堆栈溢出。 一个可行的解决方案是使用nextInt(3)而不是三分之一的时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.