使用Fibonacci递归打印1到n

时间:2014-12-11 12:14:04

标签: c++ algorithm recursion fibonacci

我想在我的函数中打印从1到n的Fibonacci系列。 我知道我可以通过编写常规Fibonacci并在for块中使用它来打印1到N来做到这一点。像这样:

#include <iostream>
using namespace std;

int fibo(int);

int main(){
    for (int i = 0; i < 5; i++)
        cout << fibo(5);
    system("pause");
    return 0;
}

int fibo(int n){
    if (n == 1 || n == 2)
        return 1;
    else
        return fibo(n - 1) + fibo(n - 2);
}

但我的问题是,如果没有我的功能,我就无法做到 我的意思是我想用递归算法打印它 这是我到目前为止的代码

#include <iostream>
using namespace std;

int fibo(int, bool);

int main(){
    fibo(5, false);
    system("pause");
    return 0;
}

int fibo(int n, bool IsPrinted){
    if (n == 1 || n == 2){
        if (!IsPrinted)
            cout << 1 << endl;
        return 1;
    }
    else{
        int temp = fibo(n - 1, IsPrinted) + fibo(n - 2, IsPrinted);
        if (!IsPrinted){
            cout << temp << endl;
            IsPrinted = true;
        }
        return temp;
    }
}

2 个答案:

答案 0 :(得分:0)

常见的解决方案是使用memoization:

int fibo(int n)
{
    static std::map<int,int> memo;
    auto it=memo.find(n);
    if(it!=std::end(memo))
    {
        return it->second;
    }

    int ret=1;
    if (n > 2)
    {
        ret = fibo(n - 1) + fibo(n - 2);
    }
    memo[n]=ret;
    return ret;
}

然后您可以安全地循环输入参数,而无需反复重新计算值:

for(int i=0;i<20;++i)
{
    std::cout<<i<<"   "<<fibo(i)<<std::endl;
}

请注意,这不仅有利于打印,还有助于计算本身(至少只要您多次调用该函数)。

除此之外,您还应考虑使用longdouble作为返回类型,因为int会更快地溢出。


编辑:好的,在您编辑之后,我不知道我的答案是否完全适合您的问题,但我认为无论如何这都是一个很好的建议。

但是这里有另一种快速的选择,我想:

int fibo(int n, bool first=true)
{
    int ret=0;
    if(n>2)
    {
        ret=fibo(n-1,false)+fibo(n-2,false);
    }
    else
    {
        ret=1;
    }

    if(first)
    {
        std::cout<<ret<<std::endl;
    }
    return ret;        
}

DEMO

答案 1 :(得分:0)

long fibo(int N, bool print) {
    long value = 0;

    if(1 == N)
        value = 1;

    if(1 < N)
        value = fibo(N-1, print) + fibo(N-2, false);

    if(print)
        std::cout << N << " => " << value << std::endl;
    return value;
}

int main(){
    fibo(5, true);
    return 0;
}

你应该意识到对fibo函数的调用会产生一棵树。树的根是fibo(5, true)中对main()的调用。由于您只想打印每个值一次,因此解决方案是决定仅在该树的最左侧分支上打印函数的值。那么规则就是:

  • 从不在正确的分支上打印(因此调用fibo(N-2, false)
  • 如果父母没有打印,则永远不会打印(以避免在儿童离开右分支的分支时打印)