2009-11-18 94 views
0

嗨,大家好,我正在研究一个大学课程的程序,该程序使用名为get_line()的方法来递归计算从网格上的一个点到另一个点的连续位置列表。当我运行它时,我在方法中最后一个return语句的行处发生堆栈溢出。我想知道是否有其他人可以查看方法,看看有没有什么看起来完全错误。该方法提供如下:java stackoverflow错误

谢谢你的帮助!

位置是包含行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

你应该重申这一点,并添加作业标签,只是为了更多的预见。 – 2009-11-18 17:37:19

+2

在Java中习惯使用以高级字符开头的所有类名; “我的位置”看起来更像是一个变量,而不是一个班级,直到我遇到心理错位并回去仔细检查。永远不要低估会议的力量! – 2009-11-18 17:53:38

+0

我不知道有一个家庭作业标签,这对那些试图回答编程问题的人有帮助吗?此外,我的问题中的第一句话是“嗨,伙计们,我正在为**大学课程**计划” – seventeen 2009-12-02 17:34:12

回答

0

首先,你播种每次进入该方法时,你随机生成,移动:

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)并且不会在三分之一的时间内转向。

+0

+1 - 简化在这里很关键,但他可能想要涵盖所有的基础。它似乎没有使用Random r,因为to不同于'r'。 – 2009-11-18 17:47:32

+0

他确实使用r在'r.nextInt(2)== 0'中进行随机步骤 – rsp 2009-11-18 18:29:28

0
+0

是的,错,但在这种情况下,它无济于事,上面的get_line方法将填满任何大小的堆栈;) – 2009-11-18 17:30:13

+0

一般来说,增加运行时堆栈是可能的,因为耗尽它通常是无限递归的标志。 – 2009-11-18 17:41:17

+1

同意,如果在正常操作中可以显示超过堆栈深度,则只应增加堆栈。这显然是无限递归。 – 2009-11-18 17:51:30

2

“to.r == from.r & & to.c == from.c” 从不计算真正提高你的运行堆栈大小...

3

什么条件,其中这两个参数为真:

if(to.r == from.r && to.c == from.c) 

在我一眼救援人员到场呃看来nextloc总是被修改,所以上面的语句永远不会是真的。

1

如果你得到一个堆栈溢出,你可能会有一个无限循环。换句话说,你的算法从来没有找到“到”点。尝试在方法开始时打印出“nextLoc”值,以查看它是否正在进行匹配。然后你可以试着找出算法出错的地方。

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

您在这里有一个递归函数。这是一个自我调用的函数。每次进行方法调用时,都会向堆栈中添加一个帧。如果递归函数没有以合理数量的递归退出,那么将会用尽堆栈空间。因此堆栈溢出。正如其他人所说,它看起来像你的一个条件总是错误的,所以你将无限递归(直到你用完堆栈空间)。这就像一个无限循环,除了硬件无法处理它,所以它崩溃而不是永远工作。