SICP 习题记录 (1)

没事干找了几个SICP上的习题做,先是一道以前只想出一种很啰嗦的写法的题目

Ex 2.18
把一个列表倒过来。不习惯在lisp里用iterative方式 >,<

(define (reverse items)
  (define (reverse-iter i k)
    (if (null? i)
        k
        (reverse-iter (cdr i)
                      (cons (car i) k))))
 
  (reverse-iter items ()))

接下来几题都是Map-Reduce思想的应用(或者照书上的说法,用enumerator - filter - map - accumulator这四个步骤操作一个list)

用到的几个函数:

(define (filter predicate sequence)
  (cond ((null? sequence) null)
        ((predicate (car sequence))
         (cons (car sequence) 
               (filter predicate (cdr sequence))))
        (else (filter predicate (cdr sequence)))))

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

(define (enumerate-interval low high)
  (if (> low high)
      null
      (cons low (enumerate-interval (+ low 
1) high))))

(define (enumerate-tree tree)
  (cond ((null? tree) null)
        ((pair? tree)
         (append (enumerate-tree (car tree))
                 (enumerate-tree (cdr tree))))
        (else (list tree))))

enumrate-tree 的功能是遍历一个树状结构,把其中的所有叶子保存在一个list中。

Ex 2.34
利用Horner's rule计算多项式结果(这公式这几天还经常碰到)

(define (hornel-eval x coefficient-sequence)
  (accumulate (lambda (this-coeff higher-terms)
                (+ this-coeff (* x higher-terms)))
              
0
              coefficient-sequence))

Ex 2.35
数出一棵树中的叶子数。这题我的做法比较土,没想到map-reduce操作上的递归,而是把叶子节点的值都改成1然后一个累加。


(define (count-leave tree)
  (accumulate +
              
0
              (map (lambda (x) 
1)
                   (enumerate-tree tree))))

其实只要递归调用主函数就行了


(define (count-leaves t)
  (accumulate + 
0 (map (lambda (x) (if (pair? x) (count-leaves x) 1)) t)))

Ex 2.36
可以理解为计算矩阵各列之和吧


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

> (accumulate-n + 0 (list (list 1 2 3) (list 4 5 6) (list 7 8 9) (list 10 11 12)))
(22 26 30)

你可能感兴趣的:(SICP 习题记录 (1))