sicp每日一題[2.38-2.39]

再思即可發表於2024-10-09

Exercise 2.38

The accumulate procedure is also known as fold-right, because it combines the first element of the sequence with the result of combining all the elements to the right. There is also a fold-left, which is similar to fold-right, except that it combines elements working in the opposite direction:

(define (fold-left op initial sequence)
  (define (iter result rest)
    (if (null? rest)
        result
        (iter (op result (car rest))
              (cdr rest))))
  (iter initial sequence))

What are the values of

(fold-right / 1 (list 1 2 3))
(fold-left / 1 (list 1 2 3))
(fold-right list nil (list 1 2 3))
(fold-left list nil (list 1 2 3))

Give a property that op should satisfy to guarantee that fold-right and fold-left will produce the same values for any sequence.


這道題還是挺簡單的,題目給的2組例子都是結果不一樣的,所以很容易就會想到跟順序無關的操作,比如加法和乘法。

(fold-right / 1 (list 1 2 3))
(fold-left / 1 (list 1 2 3))

(fold-right list nil (list 1 2 3))
(fold-left list nil (list 1 2 3))


(fold-right + 1 (list 1 2 3))
(fold-left + 1 (list 1 2 3))

(fold-right * 1 (list 1 2 3))
(fold-left * 1 (list 1 2 3))

; 執行結果
1 1/2
1/6
'(1 (2 (3 ())))
'(((() 1) 2) 3)
7
7
6
6

Exercise2.39

Complete the following definitions of reverse (Exercise 2.18) in terms of fold-right and fold-left from Exercise 2.38:

(define (reverse sequence)
  (fold-right (lambda (x y) ⟨??⟩) nil sequence))

(define (reverse sequence)
  (fold-left (lambda (x y) ⟨??⟩) nil sequence))

這道題還是有難度的,我只做出了用 fold-left 實現的部分,用 fold-right 實現的時候,開始用的 cons 和 list,順序雖然是對的,但是多了很多括號,最後我也想到了使用 append,但是一直報錯,我試了一下沒有找到解決辦法,最後去搜了一下別人的答案。。

(define (reverse-by-right sequence)
  (fold-right (lambda (x y) (append y (list x))) nil sequence))

(define (reverse-by-left sequence)
  (fold-left (lambda (x y) (cons y x)) nil sequence))

(define odds (list 1 3 5 7 9))
(reverse-by-right odds)
(reverse-by-left odds)

; 執行結果
'(9 7 5 3 1)
'(9 7 5 3 1)

相關文章