update 10/23/2014 : 기본적으로 재귀 함수는 void 함수이므로 반환 이후에 더 이상 작업 할 필요가 없습니다. 재귀 재귀 버전과 동일해야합니다. 스택 오버플로가 발생해서는 안됩니다. 실제로 꼬리 재귀 비 void 반환 형식을 시도하고 여전히 스택 오버플로 오류가 발생했습니다. 나는 그것이 꼬리 재귀이지만 컴파일러 인터프리터가 어떻게 구현하는지에 달려 있다고 생각한다.내 코드가 Java에서 스택 오버플로 오류를 일으키는 이유는 무엇입니까? 그것은 결국 종료되어야합니다. for 루프 버전은 오류를 발생시키지 않습니다.
같은 코드의 for 루프 버전으로 인해 스택 오버플로 오류가 발생하지 않습니다. 그러나 아래의 코드 (재귀 버전) 않습니다. 본질적으로 그들은 똑같은 일을해야합니다. 루프 7000 (i = 7000)에서 예외 오류가 발생했습니다.
for 루프 버전이 아닌 동안 재귀 버전에서 오류가 발생하는 이유가 궁금합니다. 의심 스럽지만 확실하지 않습니다.
//recursive version, overflow
public class Solution {
int n, low = -1, profit = 0;
int[] a;
public int maxProfit(int[] prices) {
n = prices.length;
if (n == 0 || n == 1)
return 0;
a = prices;
maxProfit(1);
return profit;
}
public void maxProfit(int i) {
if (i == n - 1) {
if (low != -1 && a[i - 1] <= a[i])
profit += a[i] - low;
return;
}
if (a[i - 1] < a[i] && low == -1) {
low = a[i - 1];
}
if (a[i - 1] > a[i] && low != -1) {
profit += a[i - 1] - low;
low = -1;
}
//System.out.print(i+",");
maxProfit(i + 1);
}
public static void main(String[] args) {
Solution sl = new Solution();
// int[] a = { 1, 9, 6, 9, 1, 7, 1, 1, 5, 9, 9, 9 };
// int[] a = { 4, 4 };
// int[] a = { 3, 2 };
// int[] a = { 1, 2, 3, 4, 3 };
// int[] a = { 3, 2, 1, 0, 4, 5, 6, 7, 10, 4, 9, 7 };
int[] a = new int[100001];
for (int i = 0; i < 100001; i++) {
a[i] = 100000 - i;
}
System.out.println();
System.out.println(sl.maxProfit(a));
}
}
100000 프레임의 호출 스택을 가질 수 있기를 기대하는 재귀 버전과 관련이있을 수 있습니다 ... – vanza
재귀 함수는 기본 사례가 히트되지 않아 스택을 푸는 경향이있는 경우 StackOverflowError를 발생시키는 경향이 있습니다 ... 기본 케이스 로직을 어지럽히거나 기본 케이스쪽으로 이동하지 않거나 너무 깊게 재연하려고 시도 할 수 있습니다 – Krease