了解递归函数的工作原理

2024-03-23

正如标题所解释的,我有一个非常基本的编程问题,但我还无法理解。过滤掉所有(极其聪明的)“为了理解递归,必须先理解递归”。网上各种帖子的回复我还是不太明白。

了解当面对不知道我们不知道的事情时,我们可能会倾向于提出错误的问题或错误地提出正确的问题我将分享我“认为”我的问题是什么,希望有类似观点的人可以分享一些一点知识将有助于为我打开递归灯泡!

这是函数(语法是用 Swift 编写的):

func sumInts(a: Int, b: Int) -> Int {
    if (a > b) {
        return 0
    } else {
        return a + sumInts(a: a + 1, b: b)
    }
}

我们将使用 2 和 5 作为参数:

println(sumInts(a: 2, b: 5))

显然答案是14。但我不清楚这个值是如何实现的。

这是我的两个难题:

  1. 递归调用该函数,直到满足条件为止。该条件是 a > b。当满足这个条件时,返回0。乍一看,我认为返回值是0,这显然是不正确的。

  2. 在每次迭代中打印出“a”的值会产生一个我期望的值:2,3,4,5(此时5+1>b满足第一个条件:a>b)但我仍然不'看看14的值是如何实现的。

我的第一个想法是类似以下的事情正在神奇地发生:

var answer = a;
answer += a+1 until a > b;
return answer;   

所以排除魔法,我只是没有得到任何东西。我很想了解正在发生的事情,而不仅仅是隐含的。

如果有人能解释一下在这种函数中技术上发生了什么以及为什么结果不为 0 以及最终如何,a + sumInts(a: a + 1, b: b) = 14,我将永远欠你的情。


1. 递归调用该函数,直到满足条件。那个条件是a > b。当满足这个条件时,返回0。乍一看,我认为返回值是0,这显然是不正确的。

这是计算机计算的内容sumInts(2,5)会想如果它能够:

I want to compute sumInts(2, 5)
for this, I need to compute sumInts(3, 5)
and add 2 to the result.
  I want to compute sumInts(3, 5)
  for this, I need to compute sumInts(4, 5)
  and add 3 to the result.
    I want to compute sumInts(4, 5)
    for this, I need to compute sumInts(5, 5)
    and add 4 to the result.
      I want to compute sumInts(5, 5)
      for this, I need to compute sumInts(6, 5)
      and add 5 to the result.
        I want to compute sumInts(6, 5)
        since 6 > 5, this is zero.
      The computation yielded 0, therefore I shall return 5 = 5 + 0.
    The computation yielded 5, therefore I shall return 9 = 4 + 5.
  The computation yielded 9, therefore I shall return 12 = 3 + 9.
The computation yielded 12, therefore I shall return 14 = 2 + 12.

如您所见,对函数的一些调用sumInts实际上返回 0,但这不是最终值,因为计算机仍然必须将 5 添加到 0,然后将 4 添加到结果中,然后添加 3,然后添加 2,正如我们计算机思想的最后四个句子所描述的那样。请注意,在递归中,计算机不仅必须计算递归调用,还必须记住如何处理递归调用返回的值。计算机内存中有一个特殊的区域,称为堆栈保存此类信息的空间是有限的,过于递归的函数可能会耗尽堆栈:这就是堆栈溢出以我们最喜爱的网站的名字命名。

你的陈述似乎隐含地假设计算机忘记了在进行递归调用时它所处的位置,但事实并非如此,这就是为什么你的结论与你的观察不符的原因。

2.在每次迭代中打印出“a”的值会产生一个我期望的值:2,3,4,5(此时5+1>b满足第一个条件:a>b)但我仍然没有看到14的值是如何实现的。

这是因为返回值不是a本身而是值的总和a以及递归调用返回的值。

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

了解递归函数的工作原理 的相关文章

  • R - 获取与用户函数中的正则表达式模式匹配的表列表

    我希望在 R 中创建一个用户函数 它合并多个使用正则表达式来查找这些表的表 在我的情况下 我想合并我的环境中以 m 开头的所有表 这正是我想要的 Reduce function merge all TRUE mget apropos m 但
  • Python 递归搜索带有嵌套键的字典

    我最近必须使用嵌套的字典 列表组合来解决实际数据系统中的问题 我为此工作了很长一段时间并提出了解决方案 但我非常不满意 我不得不求助于使用globals 和一个命名的临时全局参数 我不喜欢使用全局变量 这只是要求注入漏洞 我觉得必须有一种更
  • Scala 泛型函数值(匿名函数)- 缺少参数类型(错误)

    我是 Scala 新手 Scala 代码运行器版本 2 7 7 final 我真的不明白为什么当我们使用高阶函数时它要求调用者提供参数类型 在下面的示例中 我有一个独立的对象 Util 具有一个功能 但在Main块中 调用者必须将参数类型传
  • 小型简单结构是否应该通过 const 引用传递?

    我一直被教导非原始类型应该通过 const 引用传递 而不是尽可能通过值传递 即 void foo std string str bad void foo const std string str good 但我今天在想 也许实际上一些简单
  • Javascript:一般访问函数参数

    这是我所拥有的 var log function arg1 arg2 console log inside arg1 arg2 var wrap function fn return function args console log be
  • 识别鼠标移动的算法

    我想知道是否有任何研究 算法可以指定鼠标在识别 等字符时的偏差量使用鼠标绘制 某种光学字符识别 但可能是一个更简单的版本 是否有某种算法可以让我说用户绘制的问号确实是一个问号 而不是其他具有一定准确性的东西 就像 Windows 平板电脑软
  • 函数 SQL 中的函数

    我可以在表值函数中调用标量函数吗 Thanks 是的 只要表值函数完成后返回一个表即可 用户自定义函数可以嵌套 也就是说 一个用户定义的函数可以 呼叫另一个 嵌套级别为 被调用函数时递增 开始执行 并在以下时间递减 被调用函数完成 执行 用
  • 多维数组、Vuex 和变异

    我正在尝试添加和删除存储在 Vuex 中的多维数组中的项目 数组是一组类别 每个类别又有一个子类别 无穷大 不是简单的二维数组 示例数据集是这样的 id 123 name technology parent id null children
  • Excel VBA 中.Delete 和.Clear 的区别?

    有什么区别Worksheets 1 Cells Delete and Worksheets 1 Cells Clear 我问这个是因为我一直用 Clear清除我的工作表内容 但在我之前的帖子中我发现Worksheets 1 Cells De
  • 当平方和为N时,如何找到四个变量的所有可能值?

    A 2 B 2 C 2 D 2 N给定一个整数N 打印出整数值的所有可能组合ABCD求解方程 我猜我们可以比暴力做得更好 天真的暴力会是这样的 n 3200724 lim sqrt n 1 for a 0 a lt lim a for b
  • 函数名前的星号有什么作用?

    我对在大多数具有我不熟悉的函数声明的 C 程序中看到的内容感到困惑 void func name void param 什么是 暗示该功能 我的理解 在变量类型中的特点是它创建一个指向另一个变量的指针 因此它可以跟踪后一个变量存储在内存中的
  • Python 递归和列表

    我正在学习 python 中的递归 我有以下代码 def search l key locates key in list l if present returns location as an index else returns Fal
  • 正则表达式引擎如何解析具有递归子模式的正则表达式?

    此正则表达式匹配回文 1 2 我无法理解它是如何工作的 递归何时结束 以及正则表达式何时从递归子模式中断并转到 part Thanks 编辑 抱歉我没有解释 2 and 1 1 指第一个子模式 对其自身 2 反向引用第二个子模式的匹配 即
  • 从原点开始在离散 2D 网格上迭代向外螺旋的算法

    例如 这是预期螺旋的形状 以及迭代的每个步骤 y 16 15 14 13 12 17 4 3 2 11 18 5 0 1 10 x 19 6 7 8 9 20 21 22 23 24 其中线条是 x 轴和 y 轴 以下是算法每次迭代 返回
  • Python Tkinter,停止线程函数

    我目前正在为 3D 打印机开发 GUI 并且遇到如何停止线程函数的问题 我希望能够单击 GUI 中具有另一个功能的按钮 该按钮将阻止线程函数通过串行端口发送 G 代码字符串 目前 该函数已合并线程 以允许在打印期间触发其他函数 我非常感谢有
  • PHP:将字符串分成 8 个块,我该怎么做?

    我基本上有二进制 假设它的长度是300 我如何将它分割 就像使用爆炸一样 成 8 位块 我查看了 chunk split 但它似乎只有一个 end 参数 而不是将其放入数组的选项 或者它可以插入数组吗 末尾 8 位数字可以低于 8 如果有人
  • 无法将新地址分配给函数中的指针? [复制]

    这个问题在这里已经有答案了 不久前 我有一个编程作业 偶然发现了这个小问题 当我给一个函数一个指针作为参数时 我无法更改它指向的地址 我通过返回我想要指针指向的新地址解决了这个问题 但我仍然想知道为什么不可能操作指针参数 因为所有内存分配函
  • 为什么我的函数将布尔值更改为“on”?

    所以我是 php 编程世界的新手 我正在在线学习和其他形式等 但我找不到任何东西来帮助回答我的问题 这就是我在这里的原因 任何帮助当然不胜感激 谢谢 我想将下面的代码变成我可以调用的函数 它的工作原理如下所示 如果我选中表单中的复选框 它会
  • 求 3D 棋盘中水体积的技巧

    所以我有一个任务 我必须重新创建一个 3D 棋盘 它是一个 RxC 方块网格 每个方块的高度都不同 如果棋盘是不透水的 有人把水倒在棋盘上 直到棋盘无法容纳更多的水 那么它就会容纳固定数量的水 如果板已经容纳了最大体积的水 则倒入板上的任何
  • 将古吉拉特语文本插入 MySQL 表会产生垃圾字符和不可读的文本

    我有三个 MySQL 表 我正在向其中插入古吉拉特语内容 当我插入两个表时 它们插入得很好并且可读 但在一个表中 它显示垃圾字符 不可读的文本 我怎样才能解决这个问题 MySQL 有每个表的字符集设置 http dev mysql com

随机推荐