[英]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.