不知道如何解决 SICP 练习 1.11

2024-04-16

练习1.11 http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_thm_1.11:

一个功能f由以下规则定义f(n) = n if n < 3 and f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) if n > 3。编写一个计算过程f通过递归过程。编写一个计算过程f通过迭代过程。

递归地实现它非常简单。但我不知道如何迭代地做到这一点。我尝试与给出的斐波那契示例进行比较,但我不知道如何使用它作为类比。所以我放弃了(为我感到羞耻)并谷歌搜索一个解释 http://www.billthelizard.blogspot.com/2009/11/sicp-exercise-111.html,我发现了这个:

(define (f n)
   (if (< n 3)
       n
       (f-iter 2 1 0 n)))

(define (f-iter a b c count)
   (if (< count 3)
       a
       (f-iter (+ a (* 2 b) (* 3 c))
               a
               b
               (- count 1))))

读完后,我了解了代码及其工作原理。但我不明白的是从函数的递归定义到此所需的过程。我不明白代码是如何在某人的头脑中形成的。

您能解释一下达成解决方案所需的思维过程吗?


您需要捕获某些累加器中的状态并在每次迭代时更新状态。

如果您有使用命令式语言的经验,请想象编写一个 while 循环并在循环的每次迭代期间跟踪变量中的信息。你需要什么变量?您将如何更新它们?这正是您在Scheme 中进行迭代(尾递归)调用集所必须要做的。

换句话说,开始将其视为 while 循环而不是递归定义可能会有所帮助。最终,您将足够流畅地进行递归 -> 迭代转换,无需额外的帮助即可开始。


对于这个特定的示例,您必须仔细查看三个函数调用,因为并不能立即清楚如何表示它们。然而,这是可能的思考过程:(在Python伪代码中强调命令性)

每个递归步骤都会跟踪三件事:

f(n) = f(n - 1) + 2f(n - 2) + 3f(n - 3) 

所以我需要三个状态来跟踪当前、最后一个和倒数第二个值f。 (那是,f(n-1), f(n-2) and f(n-3)。) 给他们打电话a, b, c。我必须在每个循环内更新这些部分:

for _ in 2..n:
    a = NEWVALUE
    b = a
    c = b
return a

那么什么是NEWVALUE?好吧,现在我们已经有了代表f(n-1), f(n-2) and f(n-3),这只是递归方程:

for _ in 2..n:
    a = a + 2 * b + 3 * c
    b = a
    c = b
return a

现在剩下的就是找出初始值a, b and c。但这很容易,因为我们知道f(n) = n if n < 3.

if n < 3: return n
a = 2 # f(n-1) where n = 3
b = 1 # f(n-2)
c = 0 # f(n-3)
# now start off counting at 3
for _ in 3..n:
    a = a + 2 * b + 3 * c
    b = a
    c = b
return a

这与Scheme迭代版本还是有点不同,但我希望你现在能看到这个思考过程。

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

不知道如何解决 SICP 练习 1.11 的相关文章

  • 使用递归求数组的最小值?

    好吧 所以我一直在尝试用 Java 来理解递归 我可以完成简单的任务 例如求和 反转等 但我一直在努力做这个练习 我试图使用递归找到数组中的最小数字 但始终得到 0 0 的答案 我对递归的理解是 我需要增加一个元素 然后提供一个结束递归的基
  • F#、FParsec 和递归调用流解析器(第二次)

    感谢您的回复我的第一篇文章 https stackoverflow com questions 26853718 f fparsec and calling a stream parser recursively and 我的第二篇文章 h
  • 并行迭代器

    我正在设计一个 C 数据结构 用于图形 供并行代码 使用 OpenMP 使用 假设我想要一个能够迭代所有元素 节点 的方法 当然 这个迭代将是并行的 是否可以使用迭代器来实现此目的 迭代器应该是什么样子才能实现并行访问 在这种情况下 您会建
  • 使用递归获取嵌套对象中的所有父对象

    我有以下对象 const object id 1 name a children id 2 name b children id 3 name c id 4 name d 我需要一个接受对象和最后一个子对象的
  • Java 中的递归回溯解决填字游戏

    我需要在给定初始网格和单词的情况下解决填字游戏 单词可以多次使用或根本不使用 初始网格如下所示 这是一个单词列表示例 pain nice pal id 任务是填充占位符 水平或垂直长度 gt 1 像那样 p pain pal id i c
  • Letrec 和可重入延续

    有人告诉我 以下表达式的计算结果为 0 但许多方案的实现将其计算为 1 let cont f letrec x call with current continuation lambda c set cont c 0 y call with
  • 产量回报延迟迭代问题

    我知道yield return 利用了延迟加载 但我想知道我是否可能滥用迭代器或者很可能需要重构 我的递归迭代器方法返回给定的所有祖先PageNode包括pageNode itself public class PageNodeIterat
  • n 二叉树的后序遍历

    我需要以下代码的帮助来回答 我正在尝试使用堆栈而不是递归在 n 叉树上执行后序遍历 因为 python 有 1000 次递归的限制 我找到了相同的预序遍历代码 https www geeksforgeeks org iterative pr
  • C++ 递归变量

    我想我的问题真的很简单 但我现在尝试解决它几个小时 但我似乎不明白 我有一个 ast 树 用 boost library 创建 并通过递归迭代它 我将所有节点保存在 NodeDescriptions 列表中 其中包含实际节点的编号 实际节点
  • “foop”:命名约定?它是“foo”的辅助递归函数;后缀“p”是什么意思?

    我遇到了以下代码片段 函数定义 choose x xs choosep x xs where choosep x x choosep x x choosep x xs choosep x xs in 柯里编程语言 http en wikip
  • 如何用模板参数包的内容填充数组?

    我嵌套了与 VS 2015 一起使用的部分专用模板代码 直到我发现它不符合标准 https stackoverflow com q 3052579 2747466 我希望如此 所以我扭曲了我的代码来克服前一个问题 并且that one ht
  • 递归和大O

    我最近正在完成一项涉及递归和大 O 表示法的计算机科学作业 我相信我很好地理解了这一点 虽然当然不是完美的 但是有一个问题给我带来了最多的问题 奇怪的是 一看就知道是作业上最简单的一个 使用大哦符号提供最佳增长率来解决以下递归问题 T 1
  • 使用reduce方法的斐波那契数列

    于是 我看到有人用reduce方法来计算斐波那契数列 这是他的想法 1 0 1 1 2 1 3 2 5 3 对应于 1 1 2 3 5 8 13 21 代码如下所示 def fib reduce n initial 1 0 dummy ra
  • 哪个更快?按引用传递与按值传递 C++

    我认为按引用传递应该比按值传递更快 因为计算机不复制数据 它只是指向数据的地址 但是 请考虑以下 C 代码 include
  • 迭代 div 内的输入

    我试图通过 jQuery 迭代放置在特定 div 上的所有输入 但没有响应 我无法使用警报查看输入的值 我究竟做错了什么
  • Google Collections ImmutableMap 迭代顺序

    我需要 Google Collection 的组合ImmutableMap and LinkedHashMap 具有定义的迭代顺序的不可变映射 看起来 ImmutableMap 本身实际上已经定义了迭代顺序 至少它的文档说 http goo
  • 跟踪 C++ 中递归函数被调用的次数

    我正在尝试编写一个程序 该程序具有一个参数是字符串向量的函数 我想在该函数上使用递归 但每次调用该函数时 我想更改参数 例如 fun stringArray i 其中 i 是调用该函数的次数 因此 以更简单的方式 如下所示 但我需要跟踪函数
  • Java中的递归排列生成错误结果

    问题是生成字典排列 起初 我的代码是这样的 public class Problem24 public static void main String args permutation 123 public static void perm
  • 从when语句内的函数返回

    我想做的就是使用 when 语句返回一个值 我想要以下功能 if x return y 我正在尝试使用 when x y 但是when语句并没有以退出函数并返回y的方式进行计算 它只是愉快地继续下一行 有没有办法做到这一点而不需要制作一个看
  • 使用一次递归调用实现递归

    给定一个函数如下 f n f n 1 f n 3 f n 4 f 0 1 f 1 2 f 2 3 f 3 4 我知道使用递归来实现它 并在一个函数内进行三个递归调用 但我想在函数内仅使用一次递归调用来完成此操作 怎样才能做到呢 要实现使用

随机推荐

  • 网络响应超时错误 (create-react-native-app) (expo)

    我正在尝试在 android 中的 expo 应用程序上运行 create react native app 首先 我通过编写命令创建了项目 创建反应本机应用程序测试 然后我执行了 npm 启动 然后从expo应用程序扫描二维码 但扫描二维
  • Spring Boot Mongodb 按 ID 搜索返回 null

    我用 mongodb 创建了一个 Spring Boot 项目 当我将数据插入集合时 它会被插入 但是当我尝试从中获取数据时findOne by id基于 id 的插入值总是返回 null 我在下面给出了我的模型类和插入方法 请告诉我出了什
  • 如何在 DLL 上使用 app.config 而不是 exe

    这是一个姐妹问题以及我的第一个问题允许使用 NET 2 0 构建的 C 应用程序在 NET 4 0 4 5 上运行 https stackoverflow com questions 13461185 allow c sharp appli
  • Selenium - 在检查 HTML 之前找不到可见元素?

    我目前正在使用 Selenium 进行网络爬虫应用程序 在几个成功的模块之后 以下情况让我陷入困境 我试图找到 菜单 类的一个元素 其文本 报告 位于名为的框架内 框架 应用 很简单 对吧 应该很简单 browser webdriver C
  • 扫描仪双值 - InputMismatchException

    我尝试以最简单的方式使用扫描仪 Code double gas efficiency distance cost Scanner scanner new Scanner System in System out print Enter th
  • MongoDB更新数组的多条记录[重复]

    这个问题在这里已经有答案了 我最近开始使用 MongoDB 并且有一个关于更新文档中的数组的问题 我得到这样的结构 id ObjectId post comments user test avatar static avatars asd
  • 实体框架级联删除问题-外键设置为空

    我有以下使用实体框架映射的模型 Mitglied gt Auftrag gt Teilprojekt 我已经用外键和 删除级联 设置了数据库中的所有内容 如果我对数据库执行一些测试 一切都会正常 当我使用实体框架添加尤其是删除对象时 问题就
  • 生成 PDF 格式的 Crystal 报告...如何在新选项卡或页面中打开?

    我编写了一段代码来生成 PDF 格式的 Crystal Reports 报告 但是它在用户进行搜索并单击按钮的同一页面中打开 有什么方法可以在新选项卡或页面中打开 PDF 我的代码是 private void OpenPDF ReportD
  • Word 2007 VBA - 使一些文本变为粗体和其他斜体

    我有以下代码 用于从 Excel 单元格中选择数据并替换 Word 文档中的特定文本 出于此问题的目的 Excel 单元格已替换为纯文本字符串 数据 转到 是恒定的 那么数据 aaa bbb 可以是任何内容 直到我们到达 of 它也是恒定的
  • Idris - 在 n 维向量上映射操作

    我在 Idris 中定义 n 维向量如下 import Data Vect NDVect Num t gt rank Nat gt shape Vect rank Nat gt t Type gt Type NDVect Z t t NDV
  • 如何在 Luigi 中启用动态需求?

    我在 Luigi 中构建了一个任务管道 由于该管道将在不同的上下文中使用 因此可能需要在管道的开头或结尾包含更多任务 甚至任务之间的依赖关系完全不同 就在那时我想 嘿 为什么要在我的配置文件中声明任务之间的依赖关系 所以我在 config
  • 抽象类、接口和自动装配

    我有以下主要课程 public class Startup implements UncaughtExceptionHandler Autowired private MessageListener messageListener priv
  • 如何清空字符数组?

    有一个像 char Members 255 这样的字符数组 如何在不使用循环的情况下完全清空它 char members 255 我所说的 空 是指如果它存储了一些值 那么它就不应该 例如 如果我执行 strcat 那么旧值不应保留 mem
  • 手动合并拉取请求

    所以我在github上有以下情况 我从创建了一个新分支mainbranch并命名为userstory1 我在分支中推送了我的更改userstory1并向我的同事提出了拉取请求 他发现文件夹结构不正确 因此将我的代码文件夹重命名为mainbr
  • 如何在 XLOPER 和 VARIANT 之间编组? [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我正在开发一个 Excel 插件 XLL 它与 COM 对象进行通信 所以 我必须在 XLOPER 和
  • Blazor按钮,使用父组件@onclick

    是否可以使用父组件方法 onclick 或者我需要从子组件中调用它 假设我想调用父方法 Foo Parent page Custom component button
  • 收到错误消息 - 创建签名 apk 时“条目名称 'res/layout/test_toolbar.xml' 发生冲突”

    我已经更新了我的 android studio3 5 x to 3 6今天 在为构建变体生成签名 apk 时出现错误 显示以下消息 Entry name res layout test toolbar xml 相撞 我在整个项目中根本没有任
  • 如何从 Github 和 Bitbucket 上的 git 删除提交

    我不小心从 Django 项目中的 idea 目录中推送了文件 这些文件位于 gitignore 文件中 我正在尝试从我的 bitbucket 存储库中完全删除提交 因为我正在与该项目一起工作的其他人 并且他无法在不影响他自己的 idea
  • “等效”从不匹配的正则表达式的时间完全不同?

    我最近为这个问题计时了一堆正则表达式 永远不会与任何内容匹配的正则表达式 https stackoverflow com questions 1723182 a regex that will never be matched by any
  • 不知道如何解决 SICP 练习 1.11

    练习1 11 http mitpress mit edu sicp full text book book Z H 11 html thm 1 11 一个功能f由以下规则定义f n n if n lt 3 and f n f n 1 2f