SICP笔记

核心理念

将抽象作为克服复杂性的一种技术

构造过程抽象

组合式(+ 1 1)
解释器将组合式的各个部分求值,包括运算符和各个参数
(过程应用的)代换模型(Substitutions)把复杂组合式逐步分解成每个部分求值的结果,并非解释器的实际处理方式替换模型
正则序求值先求解操作符,最后求解后求解值。在书中涉及平方函数的调用,使得被平方的表达式被处理两次而非表达式的结果值进行平方。(square (+1 1)) 被解释成(* (+1 1) (+ 1 1)) 而非(* 2 2)
应用序求值先求参数,再求操作符
:在能够通过替换模拟的得到合法值的过程应用中,两种求值顺序会获得相同的结果。
谓词指哪些返回真或假的过程,或求得真或假的值的表达式

(define (abs x)
	(cond ((< x 0) (-x))
		  (else x)))
(define (abs x)
	(cond ((< x 0) -x)
		  ((= x 0) 0)
		  ((> x 0) x)))
(if <predicate> <consequent><alternative>)
(and <e1> ... <en>);阻断
(or <e1> ... <en>);阻断
(not <e>)

说明性数学定义,描述是什么
行动性计算机科学,描述怎么做
过程抽象隐藏一些细节,在使用时不需要弄清它是如何实现的
下文中good-enough?的判断就抽象了一个过程,不论是什么,只要能完成任务就行。

(define (sqrt x)
	(sqrt-iter 1 x))
(define (sqrt-iter guess x)
	(if (good-enough? guess x)
		guess
		(sqrt-iter (improve guess x) x))))

局部名函数参数的名字不会与调用他的地方的名字冲突。这么想lisp的宏定义会造成这样的问题,所以使用了临时变量名之类的机制。
高阶过程把过程当参数传递

内部定义和块结构

被约束的 做用域 声明这个形参的过程的体就是作用域

(define (sqrt x)
	(sqrt-iter 1.0 x))
(define (sqrt-iter guess x )
	(if (good-enough? guess x)
		guess
		(sqrt-iter (improve guss x) x)))
-> ;将sqrt-iter包进sqrt的声明里
(define (sqrt x)
	(define (sqrt-iter guess x )
		(if (good-enough? guess x)
			guess
			(sqrt-iter (improve guss x) x)))
	(sqrt-iter 1.0 x))
-> ;把x作为内部变量使用
(define (sqrt x)
	(define (sqrt-iter guess)
		(if (good-enough? guess)
			guess
			(sqrt-iter (improve guss))))
	(sqrt-iter 1.0))

值得定义哪些过程评估棋步(路线和范围)的价值
对执行一个过程的效果做出预期走棋的后果

递归和迭代

通常提到递归模式时,指过程直接或间接地引用了过程本身。

CS公开课中提到的例子

尾递归和线性递归都把一个活交给另一个人,但要求返回的东西不同
尾递归可以要求中间人一个人把他的答案还给第一个,而线性递归必须把结果还给前一个人(因为他还要做自己的计算)

存在递归模式,但是是迭代的计算过程,比如尾递归。
区别的方式之一是掐断任意过程时是否有参数之外的变量影响计算结果,如下的计算过程,其结果取决于函数之外的x * factorial(x),而非参数(- x 1)。

(define (factorial x)
	(if (= x 1) 
		x 
    	(* x (factorial (- x 1))))

复杂度

考虑空间复杂度的时候,我因为树形递归太乱而愣了一下,没理解它等于O(n)的原因。
看视频的时候跟着老师的手一个一个记,因为一条树走完往回的时候其实就不用记那边的事了,记新的路线就行。相当于施放出一定旧空间记新内容,所以没有增加。

习题1.16 1.17小记

通过xn=(x2)n/2,可以实现迭代化的计算。不过一开始对于计算不清晰,绕了很多思路。最后把步骤一行行写纸上,归纳起来就清晰多了。

xan
317
336
933
9272
81271
8127*810

一开始不理解n是奇数时,a的迭代方式为什么是a = a * x,x一直平方不会错吗?但根据计算步骤归纳起来就基本不担心了。

用高阶函数做抽象

用过程作为参数或返回值

过程作为参数

lambda构造

匿名函数
除了没有名字,跟define函数一模一样
(lambda (<formal-parameters>) <body>)

let创建局部变量

(let ((<var1><exp1>)
  (<var2><exp2>)
  .
  .
  .
  <body>)

函数内用define可以起到相同效果,只是习惯上函数内只用define定义过程

(define (f x y)
	(define a (+ 1 (* x y))
	(define b (- 1 y)
	<body>)
;=
(define (f x y)
	(let ((a (+ 1 (* x y)))
		(b (- 1 y)))
		<body>))

过程作为一般性方法

折半法寻找方程的根

先define了(search f a b)
  根据(f a) (f b)的值一个大于0一个小于0,逐步求(average a b)来逼近(f x)=0。
然后考虑f本身的特殊性
  (f a)和(f b)不一定能确定谁大于0,谁小于0,甚至可能都在0的同一侧。因此加一层包装,确保传给search的a b可以得到f x在0的两侧,同时也分配(f x)小于0的参数到a,大于0的到b。

找不动点

f(x) = x
也可以用于求平方根y*y = x -> y = x/y,变换后的f(y)=y
其中f(y)包含了x,并非无视x进行计算

(define (sqrt x)
	(fixed-point (lambda (y) (average y (/ x y))) 
	1.0)

第一级状态

带有最少限制的元素被称为具有第一级的状态,他们具有如下权利或者特权

  • 可以用变量命名
  • 可以提供给过程作为参数
  • 可以由过程作为返回结果
  • 可以包含在数据结构中

lisp给了过程第一级状态

数据抽象 Abstract Data

理念

  • 模糊数据和过程的界限
  • 除了完成当前工作所必要的的校外,不对所用数据做任何多余的假设
  • “具体”数据表示的定义,与使用数据的方式无关
  • 数据抽象的基本思想是为一类数据标识出一组操作,使对该类数据的所有行为都可以通过这组操作完成,也只通过它们完成
  • 有助于程序设计,保留不同实现方式的灵活性。(如下方引用,使用数据时不用立刻考虑数据表现形式的问题,可以通过操作函数抽象出所要的内容)

DataLayers Something like segments, vectors, numbers. If we get X of
the start point of segment L. It can be represented as (xcod (pos-s L)). Not (car (car L)). When the quest changes into get end point
of L. We can easy find pos-s want be change.Instend of finding what
car means in the other one.
更正
书中对数据抽象的优点的例子是数据表示形式改变的情况,如segment L的起点和终点形式改变时(如从两点改为(起点,斜率,长度)。不需要修改所有涉及线段的代码,只要pos-s函数仍然能返回正确的起点即可。
这样做可以让线段数据表示形式的问题被隐藏起来,至少在应用线段这个数据时不需要考虑用什么方式表示线段更好。

序对

(define x (cons 1 2))
(car x) // 1
(cdr x) //2
(口口),每个空位可以存一个对象,可以是序对。列表是序对的延伸,头是值,尾指向下一个,直到尾是Nil。

制作方式

适当的选择函数和`构造函数

用过程表示一个序对

模糊了过程和数据的边界

(define (cons x y)
	(define (dispatch m) ;lambda(m) is also right
		(cond ((= m 0) x)
			((= m 1) 1)
			(else (error "argument not 0 or 1"))))
	dispatch)
(define (car z) (z 0))
(define (cdr z) (z 1))

列表

(list a b c d e)
(define (f x y . z) <body>). 号表示剩下的实参都放到.后的形参里

(f 1 2 3 4 5 6 7) ; x 1,y 2 z (3 4 5 6 7)
(define (g . w) <body>)
(g 1 2 3 4 5 6) ; w ( 1 2 3 4 5 6)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值