计算机程序的构造和解释
本专栏是对《计算机程序的构造和解释》这本书籍上所有的练习进行解答与分享。
船长灬普朗克
这个作者很懒,什么都没留下…
展开
-
计算机程序的构造和解释 练习题3.23
双向队列,类似于我们现在的双向链表,我们把原来单项队列的cdr变成一个序对,序对car是指向前一个节点的指针,cdr是指向后一个节点的指针,具体的结构图如下。这样就构成了一个双向队列。附上完整代码#lang R5RS(define (make-deque) (cons '() '()))(define (front-ptr deque) (car deque))(define (rear-ptr deque) (cdr deque))(define (make-deque-item valu原创 2021-01-20 12:00:58 · 164 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.22
其实就是写成跟练习3.20相似的实现方式,比较简单,代码如下。#lang R5RS(define (make-queue) (let ((front-ptr '()) (rear-ptr '())) (define (set-f! v)(set! front-ptr v)) (define (set-r! v)(set! rear-ptr v)) (define (empty-queue?) (null? front-ptr))原创 2021-01-19 16:15:47 · 104 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.21
#lang R5RS(define (make-queue queue) (cons '() '()))(define (front-ptr queue) (car queue))(define (rear-ptr queue) (cdr queue))(define (set-front-ptr! queue item) (set-car! queue item))(define (set-rear-ptr! queue item) (set-cdr! queue item))(define原创 2021-01-19 14:48:55 · 128 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.19
开始想的解题思路就是判断第一个序对是否在后面每个序对的cdr中,是的话就是个环,但是这个有个问题,如果一个序列,除过第一个元素,后面的元素组成一个环,这个就变成死循环了。#lang R5RS(define (last-pair x) (if (null? (cdr x)) x (last-pair (cdr x))))(define (make-cycle x) (set-cdr! (last-pair x) x) x)(define (element-cd原创 2020-09-23 17:45:52 · 106 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.18
这道题和3.17类似,采用一个临时变量把已经存在的元素放进去,然后查看cdr在不在集合中,如果在集合中,就是个环形结构,如果遍历完整个序列,所有的元素都不重复,则序列不是环。#lang R5RS(define (last-pair x) (if (null? (cdr x)) x (last-pair (cdr x))))(define (make-cycle x) (set-cdr! (last-pair x) x) x)(define (element-原创 2020-09-23 16:48:46 · 124 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.17
添加一个临时变量emp,判断临时变量里面有没有目前判断的序对,没有的话就把这个序对添加进emp,有的话就直接算0个。当然最后可以查看emp的长度来判断有多少个序对。#lang R5RS;;判断集合中是否有该元素,注意一定要用eq?(define (element-of-set? x set) (cond ((null? set) #false) ((eq? x (car set)) #true) (else (element-of-set? x (cdr set)原创 2020-09-21 17:51:50 · 106 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.16
返回为3的情况返回为4的情况返回为7的情况不返回死循环的情况其实就是因为方法无法判断序对是不是同地址,导致同一个序对计算了多次。#lang R5RS(define (count-pairs x) (if (not (pair? x)) 0 (+ (count-pairs (car x)) (count-pairs (cdr x)) 1)))(define z1 (list 'a 'b 'c))(define x (c原创 2020-09-21 17:25:32 · 115 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.15
先看z1,z1的car和cdr指向同一个对象x,所以当改变x的car时,z1的car、cdr都改变。先看z2,z1的car和cdr指向的是两个对象x,所以当改变car的x值时,cdr的值不会改变。#lang R5RS(define (set-to-wow! x) (set-car! (car x) 'wow) x)(define x (list 'a 'b))(define z1 (cons x x))(define z2 (cons (list 'a 'b) (list 'a原创 2020-09-21 16:06:53 · 123 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.14
#lang R5RS(define (mystery x) (define (loop x y) (if (null? x) y (let ((temp (cdr x))) (set-cdr! x y) (loop temp x)))) (loop x '()))(define v (list 'a 'b 'c 'd))(define w (mystery v))(display v)(newline)(d原创 2020-08-24 19:14:00 · 131 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.13
#lang R5RS(define (last-pair x) (if (null? (cdr x)) x (last-pair (cdr x))))(define (make-cycle x) (set-cdr! (last-pair x) x) x)(define z (make-cycle (list 'a 'b 'c)))(display z)(last-pair z)运行结果,之后会陷入死循环#0=(a b c . #0#)选入死循环的原创 2020-08-24 18:05:40 · 101 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.12
缺少的部分是(b)和(b c d)#lang R5RS(define (append x y) (if (null? x) y (cons (car x) (append (cdr x) y))))(define (append! x y) (set-cdr! (last-pair x) y) x)(define (last-pair x) (if (null? (cdr x)) x (last-pair (cdr x))))(d原创 2020-08-24 17:54:12 · 115 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.11
先写出代码片段#lang racket(define (make-account balance) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! bala原创 2020-08-04 21:45:55 · 156 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.10
两个版本由于多了一层lambda表达式,会多创建一层环境,当set操作的时候,会先从E1里面找有没有这个约束,如果有的话,就改变值,如果没有继续往上层环境找。#lang racket(define (make-withdraw initial-amount) (let ((balance initial-amount)) (lambda (amount) (if (>= balance amount) (begin (set! balance (- b原创 2020-08-03 17:37:49 · 123 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.9
首先看递归版本创建的环境结构(define (factorial n) (if (= n 1) 1 (* n (factorial (- n 1)))))再看迭代版本创建的环境结构(define (factorial n) (fact-iter 1 1 n))(define (fact-iter product counter max-count) (if (> counter max-count) product (fact原创 2020-08-03 15:47:35 · 121 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.8
#lang racket(define f (let ((old 0)) (lambda (a) (let ((b old)) (begin (set! old a) b))))) (+ (f 0) (f 1))(+ (f 1) (f 0))运行结果02原创 2020-07-15 23:38:02 · 152 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.7
#lang racket(define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! bal原创 2020-07-15 23:07:28 · 116 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.6
rand-update使用线性同余法#lang racket(define (rand-update x) (let ((a 97) (c 3) (m 1000)) (modulo (+ (* a x) c) m)))(define random-init 10)(define rand (let ((x random-init)) (define func (lambda ()(set! x (rand-update x)) x)) (define原创 2020-07-14 22:26:06 · 106 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.5
#lang racket(define (estimate-pi trials) (sqrt (/ 6 (monte-carlo trials cesaro-test))))(define (cesaro-test) (= (gcd (rand) (rand)) 1))(define (monte-carlo trials experiment) (define (iter trials-remaining trials-passed) (cond ((= trials-rema原创 2020-07-14 21:34:31 · 185 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.4
将之前写的make-monitored过程添加进去,然后监视pass?谓词的调用次数,然后改造dispatch-password过程,当次数达到7次时,调用call-the-cops过程。#lang racket(define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount))原创 2020-07-12 14:53:31 · 175 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.3
#lang racket(define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! bal原创 2020-07-12 14:24:58 · 218 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.2
#lang racket(define (make-monitored f) (let ((times 0)) (define (func m) (begin (set! times (+ times 1)) (f m))) (define (dispatch m) (cond ((eq? m 'how-many-calls?) times) ((eq? m 'reset-count) (set!原创 2020-07-07 22:40:39 · 105 阅读 · 0 评论 -
计算机程序的构造和解释 练习题3.1
#lang racket(define (make-accumulator a) (lambda (amount) (begin (set! a (+ a amount)) a)))(define A (make-accumulator 5))(A 10)(A 10)原创 2020-07-07 22:21:52 · 99 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.97
容易出错的地方,在term和poly的安装包里,记得加上tag数据标签,在处理除法结果的时候一定要注意去用car取出商的部分,也就是这块(list (car (div-terms n g)) (car (div-terms d g))),其他没有什么问题 (define (reduce-terms n d) (let ((g (gcd-terms n d))) (list (car (div-terms n g)) (car (div-terms d g))))) (put 'r原创 2020-07-03 18:29:22 · 123 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.96
(a)添加gcd-factor获得系数的方法,然后将系数乘到第一个多项式上,再进行运算 (define (remainder-terms a b) (cadr (div-terms a b))) (define (gcd-factor L1 L2) (let ((t1 (first-term L1)) (t2 (first-term L2))) (let ((o1 (order t1)) (o2 (order t2))原创 2020-07-03 16:45:25 · 122 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.95
先利用2.94练习的程序,定义p1 p2 p3,然后计算q1 q2,最后求出最大公约多项式。(define p1 (make-polynomial 'x (make-sparse-terms '((2 1) (1 -2) (0 1)))))(define p2 (make-polynomial 'x (make-sparse-terms '((2 11) (0 7)))))(define p3 (make-polynomial 'x (make-sparse-terms '((1 13) (0 5))原创 2020-07-03 12:24:27 · 122 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.94
在number、ploy、terms的安装包里面都加上gcd的方法就可以了,不单独列这几个过程了,直接附上完整过程。这里加上验证多项式最大公因数结果的人工解法。第一个多项式的因式分解过程x4−x3−2x2+2x=x(x3−1)−2x(x−1)=x(x−1)(x2+x+1)−2x(x−1)=x(x−1)(x2+x−1)第二个多项式的因式分解过程x3−x=x(x2−1)=x(x−1)(x+1)所以两个多项式的最大公因数是x(x−1)也就是x2−x第一个多项式的因式分解过程\\x^4-x^3-2x^2+2原创 2020-07-02 12:24:41 · 112 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.93
在之前的程序里面添加有理数的安装包,然后修改里面的运算符为通用运算符,去掉通过最大公约数的简化过程。(define (install-rational-package) (define (numer x) (car x)) (define (denom x) (cdr x)) (define (make-rat n d) (cons n d)) (define (add-rat x y) (make-rat (add (mul (numer x) (denom y))原创 2020-07-02 11:39:31 · 110 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.92
#lang racket;put get实现(define *op-table* (make-hash))(define (put op type proc) (hash-set! *op-table* (list op type) proc))(define (get op type) (hash-ref *op-table* (list op type) #f))(define *type-coercion* (make-hash))(define (put-coercion原创 2020-07-02 11:08:49 · 134 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.91
补充完整的div-terms过程,(make-term new-o new-c)是两个最高此项的商,将商和L2的每一项相乘(mul-term-by-all-terms (make-term new-o new-c) L2),然后再用L1减去这个结果,得到的 (sub-terms L1 (mul-term-by-all-terms (make-term new-o new-c) L2)) 就是下次递归的被除数。rest-of-result是由商和余组成,直接合并商就可以。 (define (div-ter原创 2020-06-22 18:29:17 · 197 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.90
分别将练习2.88和2.89的两种表现方式封装成包,然后安装进操作表(install-sparse-polynomial-package)稀疏多项式(install-dense-polynomial-package)稠密多项式提取出一个公共谓词coeff-all-zero?来判断所有系数是否为零,将它作为判断多项式是否为零的谓词子过程。其他add-terms、sub-terms、mul-terms过程直接放进操作表就可以。#lang racket;put get实现(define *op-tab原创 2020-06-11 23:22:58 · 134 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.89
主要修改多项式这里的过程(define (add-terms L1 L2) (cond ((empty-termlist? L1) L2) ((empty-termlist? L2) L1) (else (let ((t1 (first-term L1)) (t2 (first-term L2))) (cond ((> (order L1) (order L2)) (adjoin-term原创 2020-06-11 22:53:12 · 197 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.88
#lang racket;put get实现(define *op-table* (make-hash))(define (put op type proc) (hash-set! *op-table* (list op type) proc))(define (get op type) (hash-ref *op-table* (list op type) #f))(define (attach-tag type-tag contents) (cond ((eq? type-t原创 2020-06-10 21:57:42 · 107 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.87
#lang racket(define (install-polynomial-package) (define (make-poly variable term-list) (cons variable term-list)) (define (variable p) (car p)) (define (term-lsit p) (cdr p)) (define (add-poly p1 p2) (if (same-variable? (variable p1) (va原创 2020-06-10 21:51:56 · 211 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.86
要让复数实现实部和虚部都能为有理数或者整数,只需要更改以下过程的运算符号“+”为add过程即可//原本为+号(define (add-complex z1 z2) (make-from-real-imag (+ (real-part z1) (real-part z2)) (+ (imag-part z1) (imag-part z2))))//改为add过程(define (add-complex z1 z2) (make-from原创 2020-06-07 23:08:17 · 125 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.85
#lang racket(define (square x) (* x x));put get实现(define *op-table* (make-hash))(define (put op type proc) (hash-set! *op-table* (list op type) proc))(define (get op type) (hash-ref *op-table* (list op type) #f))(define *type-coercion* (make-h原创 2020-06-07 22:27:58 · 144 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.84
加入三个辅助过程high-level?判断t1是否高于t2raise-type提升类型的层级到目标层级find-high-level从参数中找到最高层级程序的思路是找到参数里面的最高层级,然后将参数都提高的最高层级的类型,然后直接找到运算过程,进行运算。(define (high-level? type1 type2 type-list) (cond ((null? type-list) #t) ((eq? (car type-list) type2) #t)原创 2020-06-07 19:47:48 · 121 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.83
为整形和有理数都编写了相关得提升类型过程,同时加入公共方法raise x(define (raise x) (apply-generic 'raise x))//放到install-rational-package包下面(put 'raise '(rational) (lambda (x) (make-complex-from-real-imag (numer x)/(denom x) 0)))//放到install-scheme-number-package包下面(put 'raise '(s原创 2020-06-07 18:39:50 · 140 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.82
先实现一个把参数转化为目标类型得辅助过程(define (cast args target-type) (map (lambda (a) (if (eq? (type-tag a) target-type) a (let ((t1->t2 (get-coercion (type-tag a) target-type))) (if t1->t2 (t1->t2 a) a))))原创 2020-06-07 17:31:51 · 130 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.81
#lang racket(define (square x) (* x x));put get实现(define *op-table* (make-hash))(define (put op type proc) (hash-set! *op-table* (list op type) proc))(define (get op type) (hash-ref *op-table* (list op type) #f))(define *type-coercion* (make-h原创 2020-05-29 23:04:56 · 273 阅读 · 0 评论 -
计算机程序的构造和解释 练习题2.80
可以把=zero?过程做成一个包进行添加,加上需要的过程定义(define (install-zero?-package) (put '=zero? '(scheme-number) (lambda (x) (= x 0))) (define (rational=zero? x) (= (numer x) 0)) (put '=zero? '(rational) rational=zero?) (define (complex=zero? x) (and (=原创 2020-05-27 23:42:45 · 102 阅读 · 0 评论