SICP ex 2-16 2-21 Sequences

ex2-16 2-17 2-18要求給出線性表的最後一個元素值,將線性表倒置,以及對每個元素進行平方操作
給出最後一個元素比較簡單,我們直接利用遞歸檢測直到下一個元素爲空,我們給出本元素的值即可
將線性表倒置,由於之前我簡單嘗試了自己編寫append函數,發現倒置挺麻煩的,所以思路很簡單,直接利用迭代的方式就可以實現倒置
每個元素進行平方,類似於append要創建一個順序的list ,我們運用遞歸方式先展開後合併,最後結果就是順序的
以下爲代碼
(define (last x)
	(if (null? (cdr x)) (car x)
		(last (cdr x))))
(define (reserve x)
	(let ((tmp (list)))
		(define (iter a tmp) 
			(if (null? a) tmp
				(iter (cdr a) (cons (car a) tmp))))
		(iter x tmp)))
(define (square-list x)
	(if (null? x) ()
		(cons (square (car x)) (square-list (cdr x)))))

接下來的問題是給出了一個存在bug的代碼,問題是輸出結果倒置,
有了上面的經驗,我們很快就明白,它使用了迭代的方式
拿1 2 3 4來說,他先計算1的平方,然後(cons 1 nil)
然後再去計算2的平方(cons 4 (cons 1 nil))
這裏看下結果爲(4 1)顯然是倒置的
而我們的遞歸方式的會由於無法求得值,所以先展開,到最後的時候最裏面的括號開始求值,因此是順序的
以下是bug代碼
;;this code has a bug
(define (square-list x)
	(define (iter list answer)
		(if 	(null? list)
			answer
			(iter	(cdr list)
				(cons (square (car list)) answer))))
	(iter x ()))

之後,進行修改,將cons中answer與(square (car list))進行對調,顯然,這種做法是錯的
我們簡單分析一下,在某次迭代中假設answer已經是一個非空列表,然後我們調用cons
我們直接看一下結果
爲什麼這答案長得這麼醜呢,我們簡單分析一下,由於我們是把answer作爲pair的前項
我們默認的answer爲nil,因此我們最終結果爲(nil,1,4,9,16)而正確的結果應爲(1,4,9,16,nil)
顯然還是錯了
至於正確的寫法,請看前面2-19
ex2-20
本題要求運用high-order思想,抽象之前的square-list函數
比較簡單,直接上代碼
(define (mapcar f x)
	(if (null? x) ()
		(cons (f (car x)) (mapcar f (cdr x)))))


ex2-21
要求修改曾經的找零問題(第一篇博客 一下子寫了這麼多了)
使用list 來提高代碼重複使用性
比較簡單,直接給代碼
(define (cc amount kinds-of-coins)
	(cond 
		((= amount 0) 1)
		((or (< amount 0) (no-more? kinds-of-coins)) 0)
		(else (+ (cc (- amount (first-denomination kinds-of-coins)) kinds-of-coins)
			  (cc amount (except-first-denomination kinds-of-coins))))))
(define (no-more? kinds-of-coins)
	(null? kinds-of-coins))
(define (except-first-denomination kinds-of-coins)
	(cdr kinds-of-coins))
(define (first-denomination kinds-of-coins)
	(car kinds-of-coins))

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章