【问题标题】:which is a better approach for fibonacci series generation这是生成斐波那契数列的更好方法
【发布时间】:2011-05-17 05:17:24
【问题描述】:

生成斐波那契数列的两种通用方法是:

  1. traditional 方法,即在函数内部运行 for 循环。
  2. 递归

我遇到了另一个解决方案

#include <iostream>

using namespace std;

void fibo() {
 static int y = 0;
 static int x = 1;
 cout << y << endl;
 y = x + y;
 x = y - x;
}

int main() {
 for (int i = 1; i <= 1; i++) {
  fibo();
 }
 return 0;
}

此解决方案在最初的运行中看起来运行良好,但与传统和递归方法相比,这是否有任何明显的缺点?

我确信静态变量会增加空间复杂度,但至少我们没有使用递归构建函数表堆栈,对吗?

【问题讨论】:

  • 如果要重新启动序列会怎样?仅当您缓存结果或只需要序列一次时,这才真正有用。

标签: c++ fibonacci


【解决方案1】:

我可以立即看到的缺点:

  • 通过本质上使状态全局化,它不是线程安全的
  • 您只能运行一次序列,因为无法重置

我倾向于将状态保持在一个对象中的方法,您可以要求它的下一个值 - 基本上是一个迭代器。 (我从来不确定斐波那契序列映射到 C++ 迭代器的难易程度;不过它适用于 C# 和 Java IEnumerable&lt;T&gt; 和 Iterable&lt;T&gt;。)

【讨论】:

  • 让您作为第一个回答我的问题的人满足了我这一年的胃口! :D 说真的...我同意,这绝对不是线程安全的,也无法重新运行序列... -Ivar
【解决方案2】:

当您需要存储状态时(例如,当您计算斐波那契数,根据它做一些事情,然后计算另一个)时,您找到的解决方案是不错的,但是从代码中的两个位置使用它会可能会给出有趣的结果。这是因为静态变量总是相同的,无论你从哪里调用它。我会建议:

class FiboNumbers {
  public:
    FiboNumbers() :
        x_(1), y_() {}

    int getNext() {
        x_ += y_;
        y_ = x_ - y_;
        return x_;
    }

  private:
    int x_, y_;
};

这提供了相同的状态保持,但允许您创建类的多个实例,因此允许您使用不同部分的代码来计算它们自己的斐波那契数列。

小提示:我发布的代码将生成与您发布的示例相同的序列,但它将生成真正的斐波那契数列,以 0 1 1 2...

【讨论】:

    【解决方案3】:

    我是一名 C++ 学生(入读 1.5 个月)。

    就我为斐波那契数列想到的这种不同方式提供反馈。

    #include<iostream>
    
    using namespace std;
    
    void fibseries(long int n)
    {
        double x=0;double y=1;
        for (long int i=1;i<=n;i++)
         {
            if(i%2==1)
             {
                cout<<x<<" ";
                x=x+y;
             } 
            else 
             {
                cout<<y<<" ";
                y=x+y;
             }
         }
    }
    
    main()
    {
        long int n=0;
        cout<<"The number of terms ";
        cin>>n;
        fibseries(n);
        return 0;
    }
    

    【讨论】:

    • 仅在您对问题有明确答案时发布。从您的帖子看来,您是在提出另一个问题,而不是在这里回答。回答部分不是用来提出问题的
    【解决方案4】:

    我不确定这个函数到底应该做什么。它 仅在您呈现的确切循环中有效,并且与其他人一样 指出,它只工作一次。 (而且可能有一个错字 在您的循环中,因为您的完整程序输出"0",并且 没有别的。)它提供什么优势:

    int y = 0;
    int x = 1;
    for ( int i = 0; i < count; ++ i ) {
        std::cout << y <<std::endl;
        y = x + y;
        x = y - x;
    }
    

    ?它更复杂,更不健壮,也更没用。

    【讨论】:

      【解决方案5】:

      如前所述,原则上,静态变量的优点是计算 n 序列的第 n 个元素更便宜,其中 n - 1 -th 已被评估。

      除了静态变量固有的问题外,最大的缺点是您无法返回序列中的较早点,也无法很好地控制序列中的位置在给定的时间。

      按照 Sevis 的建议,使用 class 无疑是实现此类静态方法的更好方法:这使一切更安全,为您提供了一种简单的方法来返回序列开始(只需重新初始化object) 并且还可以实现更多功能,例如返回 k 步、查找当前位置等。

      【讨论】:

        【解决方案6】:

        我认为这种指针方法对你会更有用。

        void main()
        {
            int i,p, *no,factorial,summ;
        
            int fib(int p);
        
            clrscr();
        
            printf("\n Enter The Number:");
            scanf("%d", no);
            printf("\n The Fibonnacci series: \n");
        
            for(i=0; i < *no; i++)
                printf("%d\n", fib(i));
        
            getch();
        }
        
        int fib(int p)
        {
            if(p == 0)
                return(0);
            if(p >= 1 && p <= 2)
                return(1);
            else
                return(fib(p - 1) + fib(p - 2));
        }
        

        【讨论】:

        • 优点/缺点的答案在哪里?如果有的话,还可以查找一些有关如何使用 scanf 的示例。
        • 马库斯,这可能是我对这个问题的误解,抱歉……谢谢提醒我“scanf”语法(“”,@)……
        • 这是一个糟糕的答案,因为主函数具有非标准返回类型,使用非标准函数并导致未定义的行为,因为 no 未经初始化就使用了。最重要的是:fib 函数的实现具有指数运行时间(和线性堆栈空间使用),绝不比 OP 链接的“传统方法”更可取。
        猜你喜欢
        • 2011-12-18
        • 2015-04-25
        • 2021-05-11
        • 2017-11-13
        • 1970-01-01
        • 1970-01-01
        • 2012-06-11
        • 2012-04-26
        • 2011-02-20
        相关资源
        最近更新 更多