我无法理解这个斐波那契程序流程

2024-02-25

所以我对编程世界很陌生,我想我应该拿起一本书来开始学习。我买了《C# 玩家指南》第 3 版,它给你的小作业之一让我很困惑。我正在一步步调试它以帮助我理解,但程序的流程对我来说毫无意义。这里是。

      static void Main(string[] args)
        {
            for (int index = 1; index <= 10; index++)
            {
                Console.WriteLine(Fibonacci(index));
            }

            Console.ReadKey();
        }

        /// <summary>
        /// Returns a number from the Fibonacci sequence, starting at 1.
        /// Note that this implementation is not very optimized, and can
        /// take a very long time if you're looking up large numbers.
        /// </summary>
        /// <param name="number"></param>
        /// <returns></returns>
        static ulong Fibonacci(int number)
        {
            if (number == 1) { return 1; }
            if (number == 2) { return 1; }

            return Fibonacci(number - 1) + Fibonacci(number - 2);
        }

前两次它运行 for 循环,它打印出“1”和“1”,因为第一次通过索引是“1”,使得第一个 if 语句为真,第二次通过索引是“2”,使得第二个 if 语句为真。但是当它第三次运行并且索引变为 3 时,它会转到 return 语句,如果我的数学正确的话 (3-1) + (3-2) 等于 3,这是有道理的。所以我希望它能从方法 return 3 中中断并将其写入控制台窗口,但事实并非如此。相反,这次它再次运行该方法,说数字的值为 2。(好吧??) 好吧,至少它应该在第二个 if 语句处停止并再次重新打印“1”。不,它会忽略该行再次命中 return 语句。这到底是怎么回事?请解释一下这个逻辑。


有一个很好的例子来说明这种递归地狱。

请注意,插图适用于循环的一次迭代

而且,它是为此代码绘制的:

return Fibonacci(number - 2) + Fibonacci(number - 1);

由于您进行了相反的加法,因此正确的程序流程将与下图所示相反。

图片是在这里拍摄的:http://compositingprograms.com/pages/28-efficiency.html http://composingprograms.com/pages/28-efficiency.html

我称其为地狱有两个原因:

对于开发者来说很难阅读

第一次fib函数被调用时,参数为 6,它首先调用 fib(4)(树的左侧部分),然后,当结束时,调用 fib(5)(树的右侧部分)。

然而,递归对于某些情况可能非常有用,但是这所学校绝对不适合这种递归。代码的目的不仅仅是供编译器阅读,还供开发人员阅读。

效率低下

正如您所看到的,某些 fib(n) 使用相同的 n 被调用多次。

最后,这个递归算法是 O(2^n) https://stackoverflow.com/questions/360748/computational-complexity-of-fibonacci-sequence,这对于这个问题来说非常糟糕

循环效率更低

请记住,该插图仅适用于一次迭代!您可以为每个 n 绘制这样的 fib(n) 图表。

使用此方法,您将丢失之前计算的每个值,而不是重新使用它们来计算下一个值。该循环的复杂度为 O(n * 2^n)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我无法理解这个斐波那契程序流程 的相关文章

  • C++:头文件中全局函数的多重定义错误

    该函数是全局的 在头文件中定义 暂时地我想把它留在那里 头文件还构成一个具有内联函数的特定类 其中一个函数调用this全局函数 源文件不包含任何有问题的全局函数 有关错误原因的任何提示吗 如果有人感兴趣的话我可以发布代码 mainwindo
  • 使用内部构造函数实例化类

    我有一个类 其构造函数被定义为内部 这意味着我无法实例化它 虽然这可能有道理 但出于调试和研究目的 我仍然愿意做一次 是否可以通过反射来做到这一点 我知道我可以访问私有 内部成员 但是我可以调用内部构造函数吗 或者 由于构造函数没有做任何重
  • 警告:从指针目标类型中丢弃“const”限定符

    没有const char s意味着 s 是一个指向常量 char 的指针 那么为什么它给我这个警告 我并不是想改变价值观 在第一个函数中警告是return discards const qualifiers from pointer tar
  • 如何使用 C# 打印 pdf

    我在 C 应用程序中使用 进程 打印 pdf 文件 但是我无法获取打印状态 我发现可以通过 System management 和 System printing 与打印机 队列进行交互 我做了很多尝试 但都出错了使用这两个命名空间但无法打
  • boost::interprocess 准备好迎接黄金时间了吗? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 我正在开发一个由内存映射文件支持的线
  • 在 MVC 类上创建主键字段

    我是 MVC 和 C 新手 我只是偶然发现它并发现它很有趣 我遇到了一个不允许我继续的问题 这是我的代码 using System using System Collections Generic using System Linq usi
  • 浏览器收集哪些值作为回发数据?

    当页面被发送回服务器时 浏览器收集每个控件的当前值并将其粘贴到一个字符串中 然后 该回发数据通过 HTTP POST 发送回服务器 Q1 除了控件的 Text 属性和 SelectedIndexchanged 因此除了用户输入数据 之外 控
  • 将占位符文本添加到文本框

    我正在寻找一种将占位符文本添加到文本框的方法 就像在 html5 中使用文本框一样 IE 如果文本框没有文本 则会添加文本Enter some text here 当用户单击它时 占位符文本消失并允许用户输入自己的文本 如果文本框失去焦点并
  • C++ 模板参数类型推断

    我有一个这样的C 模板 template
  • initializer_list 和默认构造函数重载决策

    include
  • 使用正则表达式匹配以“Id”结尾的单词?

    如何组合一个正则表达式来匹配以 Id 结尾的单词并进行区分大小写的匹配 试试这个正则表达式 w Id b w 允许前面的单词字符Id和 b确保Id位于单词末尾 b是字边界断言
  • IClaimsTransformation 未触发

    我尝试过实施一个IClaimsTransformation我在 ASP NET CORE 3 1 Web 应用程序中找到的类 public class ClaimsTransformer IClaimsTransformation publ
  • 从 ef core 的子集合中删除一些项目

    我有一个父表和子表 其中父表与子表具有一对多关系 我想删除一些子项 并且希望父项的子集合反映该更改 如果我使用删除选定的子项RemoveRange 那么子集合不会更新 如果我使用Remove从子集合中删除子集合然后 显然 它不如使用效率高R
  • 基于 C++ 范围的 for 循环

    尝试使用基于范围的 for 循环执行某些操作 可以使用常规的 for 循环来完成 如下所示 vector
  • ASP.NET Web API Swagger(Swashbuckle)重复OperationId

    I have a web api controller like below In swagger output I am having the below image And when I want to consume it in my
  • 函数模板重载解析期间的 MSVC 与 Clang/GCC 错误,其中一个函数模板包含参数包

    当我使用参数包时 我注意到这样一种情况 如下所示 在 gcc 和 clang 中编译得很好 但在 msvc 中却不行 template
  • .NET 的 HttpWebResponse 是否会自动解压缩 GZiped 和 Deflated 响应?

    我正在尝试执行一个接受压缩响应的请求 var request HttpWebRequest HttpWebRequest Create requestUri request Headers Add HttpRequestHeader Acc
  • printf 参数不足

    我的问题是关于缺少参数的 printf 之后的行为 printf s blah blah d int integer was given as argument and not int written 我已经知道 如果格式参数不足 则行为是
  • 向每个收件人发送一封包含不同内容的电子邮件(使用抄送字段)

    在你因为这个问题 毫无意义 和 不可能 而驳回之前 请听我说完 问题 我们在使用我们的系统发送的每封电子邮件中实施跟踪像素 即具有唯一 URL 的可下载 GIF 文件 这有助于我们跟踪电子邮件的打开情况 问题是 当我们抄送一些收件人时 跟踪
  • Visual Studio 2015默认附加库

    当我在 VS 2015 中创建一个空项目时 它会自动将这些库放入 附加依赖项 中 kernel32 lib user32 lib gdi32 lib winspool lib comdlg32 lib advapi32 lib shell3

随机推荐