sicp每日一题[2.36-2.37]

果然习惯不能停,就两天没学,昨天就忘的干干净净了。。今天把昨天的补上

Exercise 2.36

The procedure accumulate-n is similar to accumulate except that it takes as its third argument a sequence of sequences, which are all assumed to have the same number of elements. It applies the designated accumulation procedure to combine all the first elements of the sequences, all the second elements of the sequences, and so on, and returns a sequence of the results. For instance, if s is a sequence containing four sequences, ((1 2 3) (4 5 6) (7 8 9) (10 11 12)),then the value of (accumulate-n + 0 s) should be the sequence (22 26 30). Fill in the missing expressions in the following definition of accumulate-n:

(define (accumulate-n op init seqs)
  (if (null? (car seqs))
      nil
      (cons (accumulate op init ⟨??⟩)
            (accumulate-n op init ⟨??⟩))))

这道题我自己没做出来,搜了一下别人的答案才发现原来这么简单。。

(define (accumulate-n op init seqs)
  (if (null? (car seqs))
      nil
      (cons (accumulate op init (map car seqs))
            (accumulate-n op init (map cdr seqs)))))


(define test (list (list 1 2 3) (list 4 5 6) (list 7 8 9) (list 10 11 12)))
(accumulate-n + 0 test)

; 执行结果
'(22 26 30)

image


这道题符号太多了,还是直接截图吧。
这道题目还是挺难的,第一个矩阵乘向量比较简单,让向量依次跟矩阵的每一行点乘即可;第二个其实我不会做,我就是随便把 cons 和 nil 填到了空出的位置,没想到一执行恰好就是我要的结果,然后我回过头去看了一下 accumulate-n 的代码,发现它其实实现的就是转置的功能;第三个首先要理解它对 n 进行转置的目的,其实 m x n 就等价于用 m 的每一行跟 n 的每一列依次做点乘,现在对 n 做了转置之后,就相当于让 m 的每一行和 n 的每一行做点乘,明白了这一点这道题就可以很容易地实现了。

; m 表示矩阵,v 表示向量,m 的行数必须等于 v 中元素的个数
; 矩阵乘向量,相当于用矩阵的每一行跟向量做点乘
(define (matrix-*-vector m v)
  (map (lambda (x) (dot-product x v)) m))

; mat 表示矩阵
(define (transpose mat)
  (accumulate-n cons nil mat))

; m, n 都表示矩阵,m 的列数必须等于 n 的行数
; 最后的结果矩阵行数等于 m 的行数,列数等于 n 的列数
(define (matrix-*-matrix m n)
  (let ((cols (transpose n)))
    (map (lambda (mat) (matrix-*-vector cols mat)) m)))


(define mat (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9)))
(define mat2 (list (list 1 2 3 4) (list 4 5 6 6) (list 6 7 8 9) (list 1 2 3 4)))
(define v (list 1 3 3 1))

(dot-product v (list 2 3 5 7))
(matrix-*-vector mat v)
(transpose mat)
(matrix-*-matrix mat mat2)

; 执行结果
33
'(20 43 60)
'((1 4 6) (2 5 7) (3 6 8) (4 6 9))
'((31 41 51 59) (66 87 108 124) (91 121 151 174))
posted @ 2024-10-08 11:25  再思即可  阅读(2)  评论(0编辑  收藏  举报