public static int rFib(int n) {
if(n == 0) {
return 0;
}
if(n == 1) {
return 1;
}
return n + rFib(n-1);
}
我正在尝试找到将在60秒内计算出的最大数字。然后,我将使用迭代方法进行比较。大于10,000的任何数字都会产生堆栈溢出错误。如何避免这种情况?
答案 0 :(得分:4)
此递归问题的一种解决方案是使用动态编程来中断递归。例如,可以应用memoization,并允许您像实施
private static Map<Integer, Integer> memo = new HashMap<>();
static {
memo.put(0, 0);
memo.put(1, 1);
}
public static int rFib(int n) {
if (memo.containsKey(n)) {
return memo.get(n);
}
int r = rFib(n - 2) + rFib(n - 1);
memo.put(n, r);
return r;
}
答案 1 :(得分:0)
不幸的是,您遇到了这个问题,它既是理解递归的最常用的例子,也是将递归应用于其中的最差的应用程序。
从fibonacci理解递归非常简单,因为它是一个非常琐碎的递归算法,您可以向某人解释并理解...这对编程递归非常有用,对吗?不幸的是,不。
很抱歉,如果我想告诉您您已经知道的事情,但是我知道fibonacci是入门编程中的第一个示例,因此我假设您来自哪里。
编程中有一个东西叫做栈。之所以称其为“原因”,是因为它就像一堆文件。调用函数时,它将调用该函数,传递参数以及知道如何从该函数返回(以及其他一些管理方面的东西)所需的所有信息放入堆栈中。当该函数递归调用自身时,它将另一张纸放在堆栈顶部。然后,该函数会放置另一个工作表。在功能完成之前,不会删除这些工作表...但是,由于一个功能无法在另一个功能完成之前完成,因此它会不断增长。
堆栈只有这么大。故意。为了避免这个问题。
通常,递归不用于此类深层问题。 (尾叫递归的人:请忽略此;如果您不知道尾叫呼入是什么:也请忽略此。)
解决此问题的方法是不这样做。人们普遍认识到,几乎在每个任意递归函数应用程序中,for
循环都会更好(更快)地工作。