[英]Stack Overflow Error java
我正在嘗試解決一個需要遞歸回溯的問題,而我的解決方案會產生 stackoverflow 錯誤。 我了解此錯誤通常表示終止條件不好,但我的終止條件似乎是正確的。 除了可能導致 stackoverflow 錯誤的不良終止條件之外,還有什么其他的嗎? 我怎樣才能找出問題所在?
編輯:抱歉試圖發布代碼,但它太丑陋了..
正如@irreputable 所說,即使您的代碼具有正確的終止條件,也可能是問題對於堆棧來說太大了(因此堆棧在達到條件之前就已用盡)。 還有第三種可能:你的遞歸進入了循環。 例如,在通過圖進行深度優先搜索時,如果您忘記將節點標記為已訪問,您最終會陷入循環,重新訪問您已經看到的節點。
您如何確定您處於這三種情況中的哪一種? 嘗試設法描述每個遞歸調用的“位置”(這通常會涉及 function 參數)。 例如,如果您正在編寫一個圖算法,其中 function 在相鄰節點上調用自身,那么節點名稱或節點索引很好地描述了遞歸 function 的位置。 在遞歸 function 的頂部,您可以打印描述,然后您將看到 function 做了什么,也許您可以判斷它是否做對了,或者它是否在循環。 您還可以將描述存儲在 HashMap 中,以檢測您是否進入了圓圈。
您總是可以使用一個使用堆棧的循環,而不是使用遞歸。 例如代替(偽代碼):
function sum(n){
if n == 0, return 0
return n + sum(n-1)
}
利用:
function sum(n){
Stack stack
while(n > 0){
stack.push(n)
n--
}
localSum = 0
while(stack not empty){
localSum += stack.pop()
}
return localSum
}
簡而言之,通過將 state 保存在本地堆棧中來模擬遞歸。
正如其他人已經提到的那樣,可能有幾個原因:
您的 memory 太小,無法將遞歸調用的數量保留在堆棧中。 大斐波那契數可能是一個很好的例子。 僅供參考,斐波那契如下(有時從零開始):
1,1,2,3,5,8,13,...
Fn = Fn-1 + Fn-2
F0 = 1, F1 = 1, n>=2
如果您的問題太大而無法在默認堆棧限制大小中修復,您可以使用 -Xss 選項為您的堆棧提供更多 memory。
如果您的代碼是正確的,那么堆棧對於您的問題來說太小了。 我們沒有真正的圖靈機。
有兩個常見的編碼錯誤可能導致您的程序進入無限循環(並因此導致堆棧溢出):
例子:
public static int factorial( int n ){
if( n < n ) // Bad termination condition
return 1;
else
return n*factorial(n+1); // Bad recursion call
}
否則,您的程序可能只是運行正常而堆棧太小。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.