我正在编写一个递归算法来计算Java中的Fibonacci数,作为编程101课程的一部分。这是代码:
public class Fib {
public static void main(String[] args) {
Fib fib = new Fib();
}
public Fib() {
int end = 9;
long[] nums = new long[2];
printFib(0, end, nums);
}
private void printFib(int i, int end, long[] nums) {
while(i < end) {
if(i == 0 || i == 1) {
nums[i] = 1;
System.out.println("1");
} else {
long fib;
fib = 0;
fib += (nums[0] + nums[1]);
nums[0] = nums[1];
nums[1] = fib;
System.out.println(fib);
}
i++;
printFib(i, end, nums);
}
}
}
当我逐步执行该程序时,它按预期工作,直到i
变为等于end
,该变量告诉printFib
方法它应该打印出多少斐波纳契数。如果ì
等于end
while(i < 1)
,则按预期返回false,程序将转到上一个}
,现在您(我)
期望程序返回我最初调用函数的构造函数,程序应该退出,但事实并非如此。该程序返回到while语句,并以某种方式再次评估为false。然后它再次做同样的事情,除了它第二次将i
减少1(什么?!)然后在到达if语句时进入else
子句。然后,它会在1到2之间一次又一次地从i
中减去相同的数量。我已经向我的老师询问了这个问题并且他无法解释它。
如果我将while
替换为if
,该程序的工作方式与我的预期完全相同,那么可能有一些我不知道的while
内容。
修改
所以我现在意识到每次调用方法时i
都有一个不同的值存储,当方法退出并且i
= end
时,程序会回到之前的调用中有不同的价值。
答案 0 :(得分:4)
您实施了迭代算法来计算斐波那契数列。这就是while循环的作用。在最后进行递归调用 - printFib(i, end, nums)
- 是没有意义的。
如果您打算使用递归实现,则不需要整个while循环。
答案 1 :(得分:1)
此代码对我来说并不合适。
我建议你不要用你的方法打印。将值返回到main并打印。
你的递归方法不应该有一个while循环。那个迭代 - 正是你在这里试图避免的。
你的方法应该有一个停止条件和一个自己的调用。这不是你正在做的事情。
这样想:
/**
* Recursive Fibonnaci
* User: mduffy
* Date: 2/11/2015
* Time: 8:50 AM
* @link http://stackoverflow.com/questions/28455798/strange-behavior-in-recursive-algorithm/28455863#28455863
*/
public class Math {
private static Map<Integer, Integer> memo = new ConcurrentHashMap<Integer, Integer>();
public static void main(String [] args) {
for (String arg : args) {
int n = Integer.valueOf(arg);
System.out.println(String.format("n: %d fib(n): %d", n, fibonnaci(n)));
}
}
public static int fibonnaci(int n) {
if (n < 0) throw new IllegalArgumentException("index cannot be negative");
int value = 0;
if (memo.containsKey(n)) {
value = memo.get(n);
} else {
if (n <= 1) {
value = n;
} else {
value = fibonnaci(n-1)+fibonnaci(n-2);
}
memo.put(n, value);
}
return value;
}
}
答案 2 :(得分:-1)
基本上这种情况正在发生,因为我猜你正在考虑我作为参考,它将影响调用子Fibunacci方法的Fibunacci方法的基本调用。这将最终导致许多对fibunacci方法的调用。
在我看来,循环在你的递归求解方式中没有意义。