sicp習題2.33-2.39嚐試解答
這一節的內容非常有趣,通過將序列作為interface,在此基礎上進而提取出各種高階操作(map,filter,accumulate,enumerate等),由此引出模塊化設計的討論。模塊化設計帶來複雜性的降低,同時可能引入性能上的損失,比如書中對sum-odd-squares過程的兩種寫法,原來的寫法枚舉列表元素的過程散落在累積、過濾、映射的過程中,主要一次循環就夠了,而通過三個高階過程來操作反而需要3次的遍曆。習題2.33,將map,append,length基本過程用累積操作重新定義,聯係以往的實現通過觀察和測試可以得出:
(define (map p sequence)
(accumulate (lambda(x y)
(cons (p x) y))
() sequence))
(define (append seq1 seq2)
(accumulate cons seq2 seq1))
(define (length sequence)
(accumulate (lambda(x y)
(+ 1 y))
0 sequence))
難點就在於累積的操作。(accumulate (lambda(x y)
(cons (p x) y))
() sequence))
(define (append seq1 seq2)
(accumulate cons seq2 seq1))
(define (length sequence)
(accumulate (lambda(x y)
(+ 1 y))
0 sequence))
習題2.34,Horner規則求多項式,難點也是累積操作的定義:
(define (horner-eval x coefficient-sequence)
(accumulate (lambda(this-coeff higher-terms)
(+ this-coeff (* x higher-terms)))
0 coefficient-sequence))
隻要記住lambda中的y其實是另一個遞歸的accumulate就比較容易完成了。(accumulate (lambda(this-coeff higher-terms)
(+ this-coeff (* x higher-terms)))
0 coefficient-sequence))
測試下:
> (horner-eval 2 (list 1 3 0 5 0 1))
79
79
習題2.35,利用map和accumulate重新定義count-leaves統計樹的節點數目:
(define (count-leaves t)
(accumulate + 0 (map (lambda (x) (if (pair? x) (count-leaves x) 1)) t)))
map過程的參數op是過程(accumulate + 0 (map (lambda (x) (if (pair? x) (count-leaves x) 1)) t)))
(lambda (x) (if (pair? x) (count-leaves x) 1))
當x是列表,遞歸調用count-leaves,否則返回個數1
習題2.36,列表的列表,因此map過程的第一個參數是一個過程作用於列表中的每個列表,當然是采用car將它們首項取出然後進行op操作,因此:
(define (accumulate-n op init seqs)
(if (null? (car seqs))
()
(cons (accumulate op init (map car seqs))
(accumulate-n op init (map cdr seqs)))))
(if (null? (car seqs))
()
(cons (accumulate op init (map car seqs))
(accumulate-n op init (map cdr seqs)))))
習題2.37,list作為Lisp的基本結構可以演化出各式各樣的複雜結構,比如此題就將列表作為矢量,矢量通過組合成為矩陣,3個解答就是矩陣的運算:
(define (dot-product v w)
(accumulate + 0 (map * v w)))
(define (matrix-*-vector m v)
(map (lambda (x) (dot-product x v)) m))
(define (transpose mat)
(accumulate-n cons () mat))
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (x) (matrix-*-vector cols x)) m)))
知道矩陣運算的定義得出結果並不困難。(accumulate + 0 (map * v w)))
(define (matrix-*-vector m v)
(map (lambda (x) (dot-product x v)) m))
(define (transpose mat)
(accumulate-n cons () mat))
(define (matrix-*-matrix m n)
(let ((cols (transpose n)))
(map (lambda (x) (matrix-*-vector cols x)) m)))
習題2.38,計算下結果:
> (fold-right / 1 (list 1 2 3))
1 1/2
;也就是3/2
> (fold-left / 1 (list 1 2 3))
1/6
> (fold-right list () (list 1 2 3))
(1 (2 (3 ())))
> (fold-left list () (list 1 2 3))
(((() 1) 2) 3)
1 1/2
;也就是3/2
> (fold-left / 1 (list 1 2 3))
1/6
> (fold-right list () (list 1 2 3))
(1 (2 (3 ())))
> (fold-left list () (list 1 2 3))
(((() 1) 2) 3)
如果想使這兩個過程的結果相同,op需要滿足交換率和結合率的條件。
習題2.39:
;2.39
(define (reverse-list sequence)
(fold-right (lambda(x y)(append y (list x))) () sequence))
(define (reverse-list2 sequence)
(fold-left (lambda(x y) (cons y x)) () sequence))
(define (reverse-list sequence)
(fold-right (lambda(x y)(append y (list x))) () sequence))
(define (reverse-list2 sequence)
(fold-left (lambda(x y) (cons y x)) () sequence))
文章轉自莊周夢蝶 ,原文發布時間5.17
最後更新:2017-05-17 14:02:06
上一篇:
redhat9安裝jdk5、ruby和Erlang備忘
下一篇:
對org.springframework.beans.CachedIntrospectionResults的再次解讀
rsync cannot delete non-empty directory
字典樹-百度之星-Xor Sum
解決httpclient傳中文亂碼問題
諾獎得主Wilczek:人工智能正在解放我們的大腦
extra qualification ‘ContourLine::’ on member ‘GetLengthBetweenPoint’ [-fpermissive] 的解決方法
智能停車正成為智能交通中的主要應用場景
SQL常用函數及語句(不斷更新)
mac係統下nginx的詳細安裝過程及使用(適合新手)
Struts中提示Invalid result location value/parameter
5天2億活躍用戶,QQ新春天降紅包活動後台技術揭密