2009-11-18 91 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

您在這裏有一個遞歸函數。這是一個自我調用的函數。每次進行方法調用時,都會向堆棧中添加一個幀。如果遞歸函數沒有以合理數量的遞歸退出,那麼將會用盡堆棧空間。因此堆棧溢出。正如其他人所說,它看起來像你的一個條件總是錯誤的,所以你將無限遞歸(直到你用完堆棧空間)。這就像一個無限循環,除了硬件無法處理它,所以它崩潰而不是永遠工作。