序列操作练习2.35-2.39

练习2.35 将2.2.2节的count-leave重新定义为一个累积

点击查看代码
(define (count-leave t)
    (accumulate + 0 
                    (map (lambda (sub-tree)
                            (if (pair? sub-tree)
                                (count-leave sub-tree)
                                1))
                                t)))
练习2.36 累积同一位置的元素
点击查看代码
(define (accumulate-n op init seqs)
    (if (null? (car seqs))
        nil
        (cons (accumulate op init (map (lambda (x) (car x)) seqs))
                (accumulate-n op init (map (lambda (x) (cdr x)) seqs)))))
(define s (list (list 1 2 3)(list 4 5 6)(list 7 8 9)(list 10 11 12)))
(accumulate-n + 0 s)
(22 26 30)
练习2.37 假定我们将向量v=(vi)表示为数的序列,将矩阵m=(m0)表示为向量(矩阵行)的序列,对于这种表示,我们可以用序列操作简洁的表达基本的矩阵与向量运算。
点击查看代码
;矩阵的点积
(define (dot-product v w)
    (accumulate + 0 (map * v w)))
;求向量
(define (matrix-*-vector m v)
    (map (lambda (x) ( * x v)) m))
;矩阵的转置
(define (transpose mat)
    (accumulate-n cons nil mat))
;矩阵的乘法
(define (matrix-*-matrix m n)
    (let ((cols (transpose n)))
        (map (lambda (x) (matrix-*-vector cols x)) m)))
练习2.38 过程accumulate也被称为fold-right,因为它将序列第一个元素组合到右边所有元素的组合结果上,也有一个fold-left,反方向去操纵各个元素: (define (fold-left op initial sequence) (define (iter result rest) (if (null? rest) result (iter (op result (car rest)) (cdr rest)))) (iter initial sequence)) 下列表达式的值是什么:
点击查看代码
(fold-left / 1  (list 1 2 3))
1/6
(fold-right / 1 (list 1 2 3))
3/2
(fold-left list nil (list 1 2 3))
(((() 1) 2) 3)
(fold-right list nil (list 1 2 3))
(1 (2 (3 ())))
如果要求用某个op时保证fold-right和fold-left对任何序列都产生同样结果,指出op应该满足的性质:

练习2.39 基于练习2.38的fold-right和fold-left完成reverse(练习2.18)下面的定义:

点击查看代码
;fold-right形式
(define (reverse sequence)
    (fold-right (lambda (x y) (append (list x) y)) nil sequence))
(reverse (list 1 2 3))
(3 2 1)
;fold-left形式
(define (reverse sequence)
    (fold-left (lambda (x y) (append x (list y))) nil sequence))
(reverse (list 1 2 3))
(3 2 1)
posted @ 2025-12-18 17:49  檐上落白luckin  阅读(7)  评论(0)    收藏  举报