返回

日拱一卒,伯克利CS61A,作业10全解析

闲谈

大家好,欢迎来到日拱一卒,我是梁唐。本文始发于公众号:Coder梁。

我们今天继续来肝伯克利CS61A这门公开课,这次我们一起来看的是作业10。

作业原文说明:

Github:

这次的作业一共有3题,难度都不算很大,但是需要我们对Lisp语言的语法和运行机制有比较深入的了解。

1. 函数式编程范式

1.1

  • 我们这里有一个函数 double,它接收一个参数 n,并返回这个参数的2倍。
  • 这里有一个函数 triple,它接收一个参数 n,并返回这个参数的3倍。
  • 现在,我想要编写一个函数 compose,它可以接收两个函数作为参数,并返回一个组合函数,这个组合函数可以先调用第一个函数,然后再调用第二个函数。
  • 举个例子,我们可以使用 compose(double, triple) 来创建一个组合函数,这个组合函数可以先将一个数乘以2,然后再将结果乘以3。

1.2

  • 我们现在已经有了 compose 函数,我们可以用它来编写一个函数 multiply_all,它可以接收一个数字列表作为参数,并返回这些数字的乘积。
  • 我们可以使用 foldl 函数来编写 multiply_all 函数,foldl 函数接收一个函数和一个列表作为参数,并返回一个值。
  • foldl 函数从列表的第一个元素开始,依次将每个元素传递给给定的函数,并将函数的返回值作为下一个元素的输入。
  • foldl 函数处理完所有的元素后,它将返回函数的最终返回值。

2. 递归

2.1

  • 我们现在要编写一个函数 factorial,它可以接收一个数字作为参数,并返回这个数字的阶乘。
  • 阶乘的定义是:n! = n * (n-1)!
  • 我们可以使用递归来编写 factorial 函数,递归是指一个函数调用它自身。
  • factorial 函数中,我们可以使用递归来计算 n-1 的阶乘,然后将结果与 n 相乘得到 n 的阶乘。

2.2

  • 我们现在要编写一个函数 gcd,它可以接收两个数字作为参数,并返回这两个数字的最大公约数。
  • 最大公约数是指两个数字的最大公约数。
  • 我们可以使用欧几里得算法来编写 gcd 函数,欧几里得算法是一个计算两个数字最大公约数的算法。
  • 欧几里得算法的原理是:两个数字的最大公约数等于其中一个数字与另一个数字除以这个数字的余数的最大公约数。

3. 高阶函数

3.1

  • 我们现在要编写一个函数 map,它可以接收一个函数和一个列表作为参数,并返回一个包含函数调用列表中每个元素的结果的新列表。
  • 我们可以使用 foldl 函数来编写 map 函数,foldl 函数接收一个函数和一个列表作为参数,并返回一个值。
  • foldl 函数从列表的第一个元素开始,依次将每个元素传递给给定的函数,并将函数的返回值作为下一个元素的输入。
  • foldl 函数处理完所有的元素后,它将返回函数的最终返回值。

3.2

  • 我们现在要编写一个函数 filter,它可以接收一个函数和一个列表作为参数,并返回一个包含列表中满足给定函数的元素的新列表。
  • 我们可以使用 foldl 函数来编写 filter 函数,foldl 函数接收一个函数和一个列表作为参数,并返回一个值。
  • foldl 函数从列表的第一个元素开始,依次将每个元素传递给给定的函数,并将函数的返回值作为下一个元素的输入。
  • foldl 函数处理完所有的元素后,它将返回函数的最终返回值。

好了,以上就是作业10的全部内容。希望大家能够通过这3道习题,对Lisp语言和计算机科学基础知识有更深入的了解。