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

上节课讲了关于序对的构建使用(cons),闭包以及过程和参数抽象的思考
https://blog.csdn.net/Changed117/article/details/109494109
视频地址
https://www.bilibili.com/video/BV1Xx41117tr
通过序对创建一个坐标向量
在这里插入图片描述

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

使用MAP来处理(1.2.3.4)*10的方法就是在这里插入图片描述
如果掌握了这种通用模式。而不是一种针对特定解决的模式,你就会发现共性。你只要给出一个处理过程&

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1,过程作为返回值 在1.3中我们明白了高阶函数之后,“用一个过程作为另外一个过程的返回值”则是稀松平常的事情了,比如下面的代码: (define (f x) (+ x 1)) (define (g) f) ((g) 2) 函数g没有参数,其返回值为函数f,所以((g) 2)就运算结果就是(f 2),最后运算结果为3。 上面是用一个已命名的函数作为返回结果的,相应的,也可以将一个“匿名过程”作为结果返回,这里的“匿名过程”也就是我们的Lambda表达式,所以上面的代码可以改造成: (define (g) (lambda (x) (+ x 1))) ((g) 2) 那么((g) 2)的运算结果就是((lambda (x) (+ x 1)) 2),最后运算结果为3。 2,牛顿法 学到这里,你可能需要复习一下高等数学的基本内容,包括“导数”和“微分”,高数的在线教材可以在这里找到:http://sxyd.sdut.edu.cn/gaoshu1/index.htm 关于牛顿法的介绍可以看这里:http://en.wikipedia.org/wiki/Newton%27s_method ,下面是程序: (define (close-enough? v1 v2) (< (abs (- v1 v2)) 0.000000001)) ;定义不动点函数 (define (fixed-point f first-guess) (define (try guess step-count) (let ((next (f guess))) (if (close-enough? guess next) next (try next (+ step-count 1))))) (try first-guess 0)) ;定义导数函数 (define (D f) (lambda (x dx) (/ (- (f (+ x dx)) (f x)) dx))) ;牛顿法 (define (newton g first-guess) (fixed-point (lambda (x) (- x (/ (g x) ((D g) x 0.000000001)))) first-guess)) ;平方 (define (square x) (* x x)) ;定义开方,来测试下牛顿法 (define (sq x) (newton (lambda (y) (- (square y) x)) 1.0)) (sq 5) 3,“一等公民” 这里列出了程序语言中作为“一等公民”的语言元素所具备的几个“特权”: 可以用变量命名 可以作为过程参数 可以作为过程返回结果 可以被包含在数据结构中 4,练习1.40 求三次方程 x^3 + ax^2 + bx + c 的零点。 首先,证明 函数f(x) = x^3 + ax^2 + bx + c 是“可微”的: 由可导和可微的性质知道,可导和可微互为充要条件,所以,要证可微我们可以先证可导, f ’ (x) = (x^3)’ + (ax^2)’ + (bx)’ + (c)’ = 3x^2 + 2ax + b 所以f(x)的导数存在,那么f(x)可导,其必定可微。 其次,利用“牛顿法”:如果f(x)是可微函数,那么f(x)=0的一个解就是函数(x – f(x)/df(x)的一个不动点,其中df(x)是f(x)的导数。所以我们可以轻松得到下面的代码: (define (close-enough? v1 v2) (< (abs (- v1 v2)) 0.000000001)) ;定义不动点函数 (define (fixed-point f first-guess) (define (try guess step-count) (let ((next (f guess))) (if (close-enough? guess next) next (try next (+ step-count 1))))) (try first-guess 0)) ;定义导数函数 (define (D f) (lambda (x dx) (/ (- (f (+ x dx)) (f x)) dx))) ;牛顿法 (define (newton g first-guess) (fixed-point (lambda (x) (- x (/ (g x) ((D g) x 0.000000001)))) first-guess)) ;定义cubic函数,也就是我们题目中所谓的f(x) (define (cubic a b c) (lambda (x) (+ (* x x x) (* a x x) (* b x) c))) ;随便定义几个系数 (define a 3) (define b 5) (define c 8) (define result (newton (cubic a b c) 1.0)) ;定义一个验证过程,让其验证得到的解,是否让方程成立 (define (validate x) (= 0 (+ (* x x x) (* a x x) (* b x) c))) ;输出结果 result ;验证结果 (validate result) 比如上面我们计算 x^3 + 3x^2 + 5x + 8 = 0, 其一个解为:-2.3282688556686084 .....

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值