嘿伙计们,我正在研究一个大学课程的程序,该程序使用一个名为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.
}
}
答案 0 :(得分:3)
这两个参数的真实条件是什么:
if(to.r == from.r && to.c == from.c)
在我浏览过程中,nextloc
似乎总是被修改,所以上面的陈述永远不会成真。
答案 1 :(得分:2)
“to.r == from.r&amp;&amp; to.c == from.c”永远不会评估为真......
答案 2 :(得分:1)
如果你得到堆栈溢出,你可能有一个无限循环。换句话说,您的算法永远不会找到“到”点。尝试在方法开头打印出“nextLoc”值,看看它是否在进行匹配和从匹配方面取得任何进展。然后你可以试着找出算法出错的地方。
答案 3 :(得分:1)
这里有一个递归函数。这是一个自称的功能。每次进行方法调用时,都会向堆栈添加一个框架。如果您的递归函数没有以合理数量的递归退出,那么您将耗尽堆栈空间。因此堆栈溢出。正如其他人所说,看起来你的一个条件总是假的,所以你将无限递归(直到你用完堆栈空间)。这就像一个无限循环,除了硬件无法处理它所以它崩溃而不是永远工作。
答案 4 :(得分:0)
通过-Xss
增加运行时堆栈大小
http://forums.sun.com/thread.jspa?threadID=756468
答案 5 :(得分:0)
如果你简化代码,你可能会更容易看到问题,它中有不必要的重复。您的行和列操作可以是独立的
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;
答案 6 :(得分:0)
首先,每次进入方法时都要播种随机生成器,移动:
Random r = new Random();
到该类的属性。
其次,看起来如果你的方法返回,它只会返回一个空的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)而不是三分之一的时间。