修复Java中的StackOverflower错误
我对stacks有点陌生,所以我不太确定我是否完全理解StackOverflowerr所包含的内容。我确实读过,它主要发生在永不结束的递归中修复Java中的StackOverflower错误,java,recursion,stack-overflow,Java,Recursion,Stack Overflow,我对stacks有点陌生,所以我不太确定我是否完全理解StackOverflowerr所包含的内容。我确实读过,它主要发生在永不结束的递归中 public double calculateLeibniz(double pi, double x, long l) { if (l == 10000) { return pi; } if (l % 2 == 0) { pi -= (1.0/x); return calculateL
public double calculateLeibniz(double pi, double x, long l) {
if (l == 10000) {
return pi;
}
if (l % 2 == 0) {
pi -= (1.0/x);
return calculateLeibniz(pi, x + 2.0, l + 1);
} else {
pi += (1.0/x);
return calculateLeibniz(pi, x + 2.0, l + 1);
}
}
我试图用莱布尼兹方法计算π,我想我应该试着调整我的递归肌肉。我不确定为什么它会返回错误,因为该方法设置为在10000次迭代后终止。使用循环会更有效,这本身是否存在错误?10000是一个相当深的堆栈!JVM无疑是在你达到“极限”之前爆炸出来的。我建议您迭代地而不是递归地重新实现您的方法。像这样的
public double calculateLeibniz(double pi, double x, int l) {
while (l < 10000) {
if (l % 2 == 0) {
pi -= 1.0/x;
} else {
pi += 1.0/x;
}
x += 2.0;
++l;
}
return pi;
}
public double calculateLeibniz(双pi,双x,int l){
而(l<10000){
如果(l%2==0){
pi-=1.0/x;
}否则{
pi+=1.0/x;
}
x+=2.0;
++l;
}
返回pi;
}
在这种情况下,您的算法的堆栈深度非常浅:具体来说是1个堆栈帧深度。是的,您正在递归10000次,这意味着您正在构建一个包含所有10000个调用的堆栈。避免递归的一个原因正是因为它做到了这一点,如果堆栈空间不足,代码将失败——这显然是正在发生的事情。递归不必是无限的,只要足够大,堆栈空间就会用完,这并不一定意味着递归没有结束。您的内存可能无法处理太多的迭代。尝试在100之后终止,看看这是否修复了错误递归通常是一个猴子解决方案。像你这样的情况也可以通过迭代轻松解决。出于某种奇怪的原因,一些教育工作者坚持用数学上递归定义的问题来演示递归,而这些问题最好通过迭代来解决。这是一个遗憾,因为计算机科学中有许多问题本质上是递归的,递归非常适合于这些问题。scheme或其他尾部递归语言中的相同递归解决方案可以很好地工作。因为我们的语言没有对递归进行优化,所以我们很快就会对递归进行优化。