SICP 习题 (2.21)解题总结: map的使用

SICP 习题 2.21 开始引入了map,准确来讲,是这道题目前的文章内容开始引入了map。

为了完成本习题,甚至说为了完成本文以后的阅读,请读者一定要理解清楚map的概念,正如书中所说,“map是一种很重要的结构,不仅因为它代表了一种公共模式,而且因为它建立起了一种处理表的高层抽象”。

虽然说得非常高大上,但是map的概念理解起来并不困难,最基本的理解就是给你一组东西,你对这组东西执行map操作的话,就是把这组东西里面的成员逐个拿出来执行对应操作。

比如(map  做朋友  土豪们)就是和土豪们中的每一个土豪都做朋友。。。。。

另外要注意的就是map的返回值,map过程会返回一个组,组成员的个数和输入组相同,组成员的值取决于对应的操作。

比如(map  做朋友  土豪们)返回的应该是“土豪朋友们”,个数和“土豪们”相同,不过一个一个都是你朋友了,因为他们都执行的做朋友的操作。

习题2.21要求我们完成的就是接受一个数值列表,然后对每一个元素执行平方操作,然后返回以平方数为元素的列表。

题中给出了两种实现方法,一种是不使用map的,一种是使用map的,而且给出了一些代码框架。

不使用map的代码框架如下:

(define (square-list-1 items)
  (if (null? items)
      ‘()
      (cons <??> <??>)))

根据我们之前遍历列表的经验我们知道这里需要使用递归,其中的第一个<??>应该是要坐的操作,第二个<??>应该是递归调用square-list。

有了思路做起来就比较简单了,完成后的代码如下:

(define (square-list-1 items)
  (if (null? items)
      ‘()
      (cons (* (car items) (car items))
	    (square-list-1 (cdr items)))))

其实,如果使用map的话就更简单,使用(lambda (x) (* x x))作为map操作就可以了,map过程会去遍历列表,将每一个元素拿出来,传递给

(lambda (x) (* x x))执行平方操作。

完成代码如下:

(define (square-list-2 items)
  (map (lambda (x) (* x x) ) items))
时间: 2024-08-01 10:31:08

SICP 习题 (2.21)解题总结: map的使用的相关文章

SICP 习题 (2.30)解题总结 : Square-Tree

SICP 习题 2.30 要求我们完成一个叫square-tree的过程,其作用和之前的square过程差不多,square过程是针对简单列表的,将列表中的所有元素求平方,然后返回新的平方数列表.不过square不能对嵌套列表进行处理,如果列表中还包含列表的话会报错. 题目要求我们实现一个square-tree的过程,当输入的列表包含另一个列表时可以对嵌套的列表进行处理,生成所有列表元素的平方数. 这个和之前几道题差不多,都是对树状列表的遍历和处理.题目还要求我们用两种方式实现,一种使用map,

SICP 习题 (2.22)解题总结: 迭代过程中的列表处理

SICP 习题 2.22是习题2.21的后续题目,题目中讲到叫Louis Reasoner的人想重写suqare-list过程,希望使用迭代计算过程,而不是递归计算过程,有关迭代计算过程和递归计算过程,如果你没什么印象了,请翻回习题1.9 的解题总结看看. 那个叫Louis Reasoner的人写的迭代版的suqre-list是这样的: (define (square-list-revert items) (define (iter things answer) (if (null? thing

SICP 习题 (1.41)解题总结

SICP 习题1.41 看似和周边的题目没有关系,突然叫我们去定义一个叫double的过程,事实上这道题的核心还是高阶函数. 题目要求我们定义一个过程double,它以一个过程作为參数,这个作为參数的过程已经约定是一个单參数过程.double过程须要返回一个过程,所返回的过程将传入的过程应用两次. 举例说.假设我们有个过程叫(扇耳光 贱人).调用这个过程会扇贱人一个耳光. 那么(double 扇耳光)会返回还有一个过程.这个过程没有名字,我们暂且叫他"扇俩耳光"吧,调用(扇俩耳光 贱人

SICP 习题 (1.46)解题总结

SICP 习题 1.46 要求我们写一个过程iterative-improve,它以两个过程为参数,其中一个参数用来检测猜测是否足够好,另一个参数用来改进猜测.过程iterative-improve应该返回另一个过程,所返回的过程接收一个参数作为初始猜测,然后不断改进猜测直到结果足够好.题目还要求我们使用iterative-improve重写1.1.7的sqrt过程和1.3.3节的fixed-point过程. 因为涉及到高阶函数,所以整个题目理解起来有一点点费劲.不过这道题作为第一章的收官题确实

SICP 习题 (1.45)解题总结

SICP 习题 1.45是对前面很多关于不动点的习题的总结. 题目回顾了我们之前在1.3.3节使用的不动点寻找方法,当寻找y -> x/y 的不动点的时候,这个变换本身不收敛,需要做一次平均阻尼才可以. 对于y -> x/(y^2)这个变换也可以通过一次平均阻尼使它变得收敛. 不过一次平均阻尼对于四次方程是不够的,就是说,对y -> x/(y^3)这样的变换,一次平均阻尼不足以使它收敛,需要做两次平均阻尼才行. 题目遵从一直以来的抽象原则,要求我们去多做几次测试,找出 y -> x

SICP 习题 (2.23)解题总结:for-each的实现

SICP 习题 2.23 要求我们实现一个for-each过程. for-each过程和map过程其实很像,只不过for-each过程不返回值,如果返回一个值的话也是不包含意义的值. map比较像一个加工厂,进去一堆东西,加工一下,出来另一堆东西. for-each更像一个蒸汽机,进去一堆煤,燃烧一下,产生能量干点活,不出来东西,真的一定要说有东西出来也是煤渣,大家不在乎的东西. 所以for-each更关注的是里面执行的操作. 其实for-each操作在我们日常使用的语言中都会有,如c语言里的f

SICP 习题 (2.10)解题总结: 区间除法中除于零的问题

SICP 习题 2.10 要求我们处理区间除法运算中除于零的问题. 题中讲到一个专业程序员Ben Bitdiddle看了Alyssa的工作后提出了除于零的问题,大家留意一下这个叫Ben的人,后面会不断出现这个人,只要是这个人提到的事情一般是对的,他的角色定位是个计算机牛人,不过是办公室经常能看到的那种牛人,后面还有更牛的. 对于区间运算的除于零的问题,处理起来也比较简单,只需要判断除数是不是为零,除数为零就报错.对于一个区间来讲,所谓为零就是这个区间横跨0,再直接一点讲就是起点是负数,终点是正数

SICP 习题 (2.2) 解题总结

SICP 习题 2.2要求我们使用这一节的数据抽象方法定义几何里"点"的概念,还要定义"线段"的概念,最后还要求我们定义midpoint-segment过程,这个过程根据参数中的线段进行计算,返回该线段的中点. 题目还给出了一个print-point过程,用于输出一个点,代码如下: (define (print-piont p) (newline) (display "(") (display (point-x p)) (display &quo

SICP 习题 (1.36)解题总结

SICP 习题 1.36 要求我们修改fixed-point函数,使它能够打印出计算中产生的近似值序列,使用练习1.22展示的newline和display方法.而后通过找出变换x => log (1000)/log(x)的不动点的方式确定x^x=1000的一个根(书中还提示你使用Scheme的基本过程log,用于计算自然对数值).然后比较一下使用平均阻尼和不用平均阻尼的计算步数.要注意的是不能使用1作为初始猜测去启动fixed-point,因为log(1)=0,会导致0除数错误. 从题目来看,