我需要编写递归算法,以显示所有小于n的斐波那契数。
例如
In:
n=400;
Out:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377
我写了这个
#include <iostream>
using namespace std;
int x=400;
int current_number;
int i=0;
int fibo(int n){
if(n==0)
return 0;
if(n==1)
return 1;
else return fibo(n-2)+fibo(n-1);
}
int main(){
while(current_number<x){
current_number=fibo(i);
if(current_number<x){
cout<<fibo(i)<<" ";
i++;
}
}
return 0;
}
但是我不确定这是否是解决此问题的正确方法。它必须是递归的,我不确定这种解决方案。有人可以给我一个更好的主意吗?
答案 0 :(得分:0)
对于我来说,这对于必须使用递归算法的情况似乎是一个很好的解决方案,该算法专注于仅计算第n个斐波那契数而不打印它。
在这种情况下,我看到两个地方可以简化代码。
第一个是fibo功能。每次调用fibo recursivley都会降到0或1,然后在备份的途中开始将这些值加在一起。您调用了fibo函数两次,以计算获取下一个数字所需的一对数字。这是非常低效的,因为它导致使用相同的参数多次调用fibo函数。最后,您可以多次计算许多fibo数,这不是必需的。 (您从外面看不到它。)
为清楚起见,以下是向您展示该机制的图片:
f(10) = f(8) + f(9)
/ \
f(8) f(9)
/ \ / \
f(7) f(6) f(7) f(8)
如您所见,对于i = 8和i = 7,f(i)函数被多次调用,对于更低的i-s,f(i)函数被调用的次数更多。
要消除此问题,您可以从零开始,然后一直向上走直到碰到边界为止。
// This function is the recursivly called function...
int fiboRecursive(i, current, previous){
// go on until i is zero
if(i > 0){
// step over to the next one...
return fiboRecursive(i-1, current+previous, current);
} else {
// return the result...
return current;
}
}
// use this function to calculate the ith fibonacci number
int fibo(i) {
return fiboRecursive(i, 0, 1);
}
您可以改善代码的第二个地方是while循环:
而不是...
while(current_number<x){
current_number=fibo(i);
if(current_number<x){
cout<<fibo(i)<<" ";
i++;
}
}
...你可以这样写:
current_number = 0;
while(current_number < x){
cout << current_number << " ";
current_number=fibo(++i);
}
优点是,您无需调用 fibo(i)两次,即可获得相同的结果,并且可以正常工作,因为第一个斐波那契数为0,因此您不必计算它。如果您不喜欢对第一个斐波那契数进行硬编码,请将此行放在while循环上方:
current_number = fibo(i);
while(current_number < x){
cout << current_number << " ";
current_number=fibo(++i);
}
但是,如果允许您也允许递归函数打印出数字,那么除了计算它们之外,还可以使用更有效的方法:
int printFibo(n, current, previous){
// we only continue as long as the current fibonacci number is less than n
if(current < n){
// print out the current fibonacci number...
cout << current << " ";
// step over to the next one...
if(current == 0){
printFibo(n, 1, 0); // special starting case
} else {
printFibo(n, current+previous, current);
}
}
}
int main(){
printFibo(400, 0, 1); // the 1 could be any number because in the first call in printFibo(...) we dont use the "previous" argument.
}
之所以更有效,是因为您最多打印出n个数字。您只需运行一次递归函数。