1.lisp奇怪的表达式,
(define a 3)
(define b 4)
(= a b)->返回#false因为lisp没有这么赋值,这是检测a是否等于b,返回false
2.正则序和应用序
正则序:完全展开而后归约,即先将表达式全部展开,在进行运算。example:
(sum-square (+ 5 1) (* 5 2))->
(+ square(+ 5 1) (square(* 5 2))->
(+(*(+ 5 1) (* + 5 1) (* (* 5 2) (* 5 2)))
然后计算
应用序:解释器先对运算符和各个运算对象求值,然后将得到的参数应用于实际参数
(sum-square (+ 5 1) (* 5 2))->
(sum-square (6) (*10))->
+(square(6) square(10))->
,........
一个例题1.5
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
(test 0 (p))
正则序和应用序是不一样的。首先,(define (p) (p)),会无限循环,导致系统kill它,所以这个事无法得出值得。在应用序中,会首先求各个表达式的值,所以应用序会导致错误,而正则序则是先展开,需要用的时候在调用,由于if判断x是等于0的,所以直接输出0,没有y的事了
3.习题1.6这道题很厉害,http://sicp.readthedocs.org/en/latest/chp1/6.html。见此解答。
根据书本 12 页所说, if 语句是一种特殊形式,当它的 predicate 部分为真时, then-clause 分支会被求值,否则的话, else-clause 分支被求值,两个 clause 只有一个会被求值。
而new-if由于是应用序,在判断的时候两个都会求值,所以无限循环了》。。。。
4.习题1.7补充知识:
数学中的浮点数是”稠密而连续”的,而计算机中的浮点数却是”稀疏不连续”的。在32位计算机里的浮点数表示为:符号位(1位)+阶码(8位)+尾数(23位)。因此,计算机中两个浮点数之间只有有限个浮点数。当然,“相邻”浮点数之间就可能相差很大。这就会带来一系列浮点数精度问题。
假设两个”相邻“的大数(用二进制表示),01111110100000000000000000000001和01111110100000000000000000000000,它们仅是尾数最后一位差1,但它们之间的差值竟高达1.0*10^31。
5.习题1.11中的迭代
习惯了递归之后看迭代还是比较不容易,关键是要找出各个变量之间的关系。fliter(a,b,c,i,n) a= a+2b+3c之类的。
http://sicp.readthedocs.org/en/latest/chp1/11.html
解答地址
6.递归的思想。
如change money,单纯的将问题分割为1.去除当前钱币之后在分的方法2.用掉一枚当前钱币的方法。这种思想值得记录,之前递归不好因为没有这种思想。
7.加强递归思想的运用,如算x的n次幂,可以分解为:{若n == 0,return 1.若n为偶数,则为x^(n/2)*2.若n为奇数,则为x*x^(n-1)}
8.练习1.16.迭代,求fast-expt的迭代版本。其实可以转化成如下:若n == 0,return 1.n为偶数,a*b^n = a*(b^2)^(n/2)
即
a->a
b->b^2
n->n/2
若为奇数,a*b^n = (a*b)*b^(n-1)
a->a*b
b->b
n->n-1
lisp code:
(define (fast-expt b n) (expt-iter b n 1))define expt-iter(b n a)
cond((= n 0) a)//等于0的时候返回a
cond(even(n)
expt-iter(b (- n 1) (* a b))
cond (odd(n)
expt-iter((* b b) (/ n 2) a)
9.练习1.19,挺难得一道题,直接贴链接
http://sicp.readthedocs.org/en/latest/chp1/19.html
10.练习1.29,
运用辛普森规则计算积分,f在(a,b)中的近似值为h/3[y0+4y1+2y2+4y3+..........+2y(n-2)+4y(n-1)+yn]
其中h = (b-a)/n,n为某个偶数,yk = f(a+kh)。确定过程。
一步步来,首先:
(define h( / (-b a)n))
yk:
(define yk
(f (+ a (* k h))))
系数k:
当下标为0或者n时,系数为1,下标为奇数时系数为4,下标为偶数系数为2.我们用一个过程来定义:
(define(facetork))
(cond ((= k 0) or (= k n))1 )
(cond even? k
4)
(cond odd? k
2)
所以大括号中的项为:
(*(factor k)yk)
综上:
(define (sim f a b n))
(define h ( / (-b a)n))
(define yk(f (+ a (* k h))))
(define(facetork))
(cond ((= k 0) or (= k n))1 )
(cond even? k
4)
(cond odd? k
2)
(define (term k(*(factor k)yk)))
(define(next k)
(+ k 1)
(if(not(even?n))
(error"n can't be odd")
(*(/h3)//最后两行是我抄的,这一行我懂,下一行的exact我猜//是趋近于,0为下限。
(sumterm(exact->inexact0)nextn))))
11. 练习2-4,一个神奇的题!看半天才看明白,直接粘别人的blog的分析吧。
(car(cons x y))
=> (car (lambda (m) (m x y)))
=> ((lambda (m) (m x y)) (lambda (p q) p))
=> ((lambda (p q) p) x y)
=>((lambda (x y) x))
=> x
12.练习2-18 用scheme语言感觉没思路,后来看了答案才想出来。
(define (reverse lst) (iter lst '())) (define (iter remained-items result) (if (null? remained-items) result (iter (cdr remained-items) (cons (car remained-items) result))))首先定义iter这个翻转函数,然后进行处理。当remain为0时,表示全部处理完了,返回result,否则,将remain的car用cons加入result中(这时的位置是cdr),继续进行判断处理。
13.练习23.··答案用了if begin语句,在此仅作记录。
(define (for-each proc items))
(if(not(nul? items)
(begin
(proc (car begin)
for-each proc cdr (items) )
14.发现了一个问题:令(1 3 ( 5 7 ) 9 ) = x
则cdr(x) = (3 (5 7 ) 9)
cdr(x ) = ((5 7 ) 9 )
car(x) = (5 7)
cdr(x) = (7)
car(x) = 7
倒数第二步的时候仍然是一个序对,要对其使用car才行,cdr是null