我正在尝试使用递归打印斐波那契数列。不幸的是,它重复打印最后一个数字。
例如;如果我输入5
,则首先打印:1
,然后0
,然后再打1
& 1
,然后2
,然后重新开始重复0 1 1 2
,然后打印3
。
#include<iostream>
using namespace std;
int fibonacci(int n)
{
if (n == 0 || n == 1)
{
cout << n << " ";
return n;
}
else
{
int sum = fibonacci(n - 1) + fibonacci(n - 2);
cout << sum << " ";
return sum;
}
}
//====================================================================
void main()
{
int n;
cout << "Please input the Limit: ";
cin >> n;
fibonacci(n);
system("pause>null");
}
答案 0 :(得分:3)
斐波那契函数的递归定义是
fib(n)= fib(n-1)+ fib(n-2)
所以只需改变
int sum = fibonacci(n - 1) + fibonacci(n - 1);
到
int sum = fibonacci(n - 1) + fibonacci(n - 2);
测试:
Please input the Limit: 5
1 0 1 1 2 1 0 1 3 1 0 1 1 2 5
Please input the Limit: 6
1 0 1 1 2 1 0 1 3 1 0 1 1 2 5 1 0 1 1 2 1 0 1 3 8
编辑1
您希望使用此算法打印斐波那契序列fib(0),fib(1),....如果你稍微提高你的输出,你会看到它对fib(5)的作用:
fib 1 = 1
fib 0 = 0
fib 2 = 1
fib 1 = 1
fib 3 = 2
fib 1 = 1
fib 0 = 0
fib 2 = 1
fib 4 = 3
fib 1 = 1
fib 0 = 0
fib 2 = 1
fib 1 = 1
fib 3 = 2
fib 5 = 5
5
如您所见,计算了不少值,这解释了打印的序列。仅计算一次结果的一种方法是Memoization。如果您使用了memoization并且只在第一次确定结果时打印出来,那么您将获得:
fib 1 = 1
fib 0 = 0
fib 2 = 1
fib 3 = 2
fib 4 = 3
fib 5 = 5
5
所以即便如此,你也没有得到你想要的订单。因此,您必须使用memoisation,并且只在流程结束时打印哈希映射。
5
fib 0 = 0
fib 1 = 1
fib 2 = 1
fib 3 = 2
fib 4 = 3
fib 5 = 5
当然,你也可以创建一个额外的循环并打印从1到n的i的fib(i)的所有值。但这可能效率很低。
编辑2
免责声明:我对C ++一无所知。我很久以前写过我的最后一个C程序。但是下面的工作,其他人会做得更好,我敢肯定。
所以这是一个使用普通数组进行memoization的简单例子,没有哈希映射。既然你没有说到目前为止你学到了哪些概念,我希望这很简单。
#include <iostream>
#define MAX 100
#define UNDEF -1
using namespace std;
int memo[MAX]; // memoization of results
int fibonacci(int n) {
int res = memo[n];
if (res != UNDEF) return res; // result has been computed before
if (n == 0 || n == 1)
res = n;
else
res = fibonacci(n - 1) + fibonacci(n - 2);
memo[n] = res; // memoize result
return res;
}
int main() {
int n, i;
do {
cout << "Please input the Limit (max " << MAX << ") : ";
cin >> n;
} while (n < 0 || n >= MAX);
for (i=0; i<=n; i++) memo[i] = UNDEF; // intitialize memo
fibonacci(n);
for (i=0; i<=n; i++) cout << memo[i] << " "; // print results
cout << endl;
}
测试:
Please input the Limit (max 100) : 40
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155
答案 1 :(得分:1)
以下是使用 memoization
的实现示例// header needed for the container: map
#include <map>
int mem_fact (int i, std::map<int, int>& m) {
// if value with key == i does not exist in m: calculate it
if (m.find(i) == m.end()) {
// the recursive calls are made only if the value doesn't already exist
m[i] = mem_fact (i - 1, m) + mem_fact (i - 2, m);
}
// if value with key == i exists, return the corresponding value
return m[i];
}
int fast_factorial (int i) {
// key (Fibonacci index) - value (Fibbonaci number)
std::map<int, int> memo;
// initialize the first two Fibonacci numbers
memo.insert(std::pair<int,int>(0, 0));
memo.insert(std::pair<int,int>(1, 1));
return mem_fact(i, memo);
}
我将留给你放置std::cout
的位置,以便每个斐波那契数字显示一次。
注意:在main()
中,您需要致电fast_factorial(num_of_fib);
答案 2 :(得分:0)
这是有效的
#include <iostream>
#include <chrono>
void _fib(unsigned int current, unsigned int max, unsigned int oneBack, unsigned int twoBack)
{
if (current == max) return;
unsigned int sum = oneBack + twoBack;
std::cout << sum << '\n';
_fib(current+1, max, sum, oneBack);
}
void fib(unsigned int max)
{
if (max >= 2)
{
std::cout << "0\n1\n";
_fib(2, max, 1, 0);
}
else if (max == 1)
{
std::cout << "0\n1\n";
}
else if (max == 0)
{
std::cout << "0\n";
}
}
int main()
{
auto start = std::chrono::system_clock::now();
fib(1000);
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> diff = end - start;
std::cout << diff.count() << "seconds";
}
答案 3 :(得分:0)
#include<iostream>
using namespace std;
int fibonacci(int n)
{
if((n==1)||(n==0))
{
return(n);
}
else
{
return(fibonacci(n-1)+fibonacci(n-2));
}
}
int main()
{
int n,i=0;
cout<<"Input the number of terms for Fibonacci Series:";
cin>>n;
cout<<"\nFibonacci Series is as follows\n";
while(i<n)
{
cout<<" "<<fibonacci(i);
i++;
}
return 0;
}
//use this one it is easy