计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)

上节课讲了关于序对的构建使用(cons),闭包以及过程和参数抽象的思考
https://blog.****.net/Changed117/article/details/109494109
视频地址
https://www.bilibili.com/video/BV1Xx41117tr
通过序对创建一个坐标向量
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)

注意这里的参数和上次的略微不同,不再传入两个参数,而是一个序对(cons),他们没有什么不同。
根据闭包的定义,序对可以非常随意的*组合,例如一个向量(两个坐标组合)
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
又或者更加随意的组合,比如我们要组合1234,有很多种组合方式
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
因此lisp中产生了某种约定,将序对组合成序对链来组合表示数据(类似单向链表的结构)
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
这是他的构造方式
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
这样就可以用CAR和CDR取出链表中的数据
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
使用CDR来取出表中的剩余数据,他表示的就是第一个序对的CDR部分所代表的数据
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
那么在表中如果我们想定义一个通用的处理过程。将表中所有的元素全部10,结果应该是这样的
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
该如何定义这个过程呢?如果使用递归策略,不停地缩放表,将取出的CAR部分
10再创建一个新表,把处理过的数据用定义序对的方式加入新的序对,处理到表尾的时候返回表末指针。过程是这样的,注意看这个过程
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
将s表缩放l倍,首先判断这个表是不是空表,空表返回表末指针,然后创建一个序对,接收表的car部分将他乘l,然后下面的过程递归调用,用表的cdr部分(也就像上面说的剩下的部分的集合)拿去继续缩放l倍,继续组合就获得了一个缩放后的表。这里创建了一个新表,并不是原来的那个表了。
既然可以这样实现的话,那就不能止步于乘,有一个通用过程MAP
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
传入l为表,p为过程两个参数,和上面的处理方式一样,新建一个表,将所有的car部分经过p过程处理然后组合在一起。

使用MAP来处理(1.2.3.4)*10的方法就是计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
如果掌握了这种通用模式。而不是一种针对特定解决的模式,你就会发现共性。你只要给出一个处理过程,和一个表,他就可以求出你想要的结果,你甚至不需要关心他是如何实现的
计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)
还有一个非常接近于MAP的处理方式,for-each计算机程序的构造和解释(SICP) Lec3a 的个人心得 (未完成)

他们的不同之处只是在于返回值,MAP返回的是一个新的表,但是for-each返回的是原来那个表,只是进行了处理(一个是else,一个是cons),其中MAP是一个递归过程(你需要得到整个表的所有参数处理后返回的末尾指针来完成你构建的新表)for-each则不需要,所以for-each是一个迭代的过程。