1.16 這個題目就是直譯一下題目裡面的公式。看開始我看了一下前面的題目,就高高興興的寫出來了。如下:
(define (even? n)
(= (remainder n 2) 0))
(define (fast-expt b n)
(cond((= n 0) 1)
((even? n) (fast-expt (* b b) (/ n 2)))
(else (* b (fast-expt b (/ (- n 1) 2))))))
後來看看題目裡面還要加乙個不變數進去,其實就是加乙個狀態記錄計算的結果。注意:如果用傳統的for迴圈來計算的話,這個地方肯定是用可變數來記錄結果的。但是函式式程式設計用的是遞迴來實現迴圈,變數計算只要在呼叫遞迴函式的時候進行就可以了,沒有必要使用中間量。其實這個的意思就是把遞迴變成迭代。
(define (even? n)
(= (remainder n 2) 0))
(define (fast-expt-iter a b n)
(cond((= n 0) a)
((even? n) (fast-expt a (* b b) (/ n 2)))
(else (* b (fast-expt (* a b) (/ (- n 1) 2))))))
(define (fast-expt b n)
(fast-expt-iter 1 b n)
不得不說,這個「不變數」把我嚇住了。其實就是乙個記錄結果的變數。還要注意的是:這個方法對於演算法的效能並沒有任何改善,演算法的複雜度還是exp(n)
1.17 這兒還用的是前面的策略,使用遞迴的思想首先得到乙個公式,如下
下面是**,注意注釋很有用
;首先實現double和halve只是為了讓程式可以執行
;實現這兩個函式的過程中可以使用任何函式和操作符
(define (double n)
(* n 2))
;這裡是實現double,所以用的是*
(define (halve n)
(div n 2))
;div使用的是地板除,而/實現的是普通的數學意義上的除法
;這兒不能用/,只能用div
(define (even? n)
(= (double (halve n)) n))
(define (fast-mul a b)
(cond ((or (= a 0) (= b 0)) 0)
((= b 1) a)
((even? b) (double (fast-mul a (halve b))))
(else (+ a (double (fast-mul a (halve b)))))))
1.18 首先還是一樣的:公式變換
**實現如下:
;首先實現double和halve只是為了讓程式可以執行
;實現這兩個函式的過程中可以使用任何函式和操作符
(define (double n)
(* n 2))
;這裡是實現double,所以用的是*
(define (halve n)
(div n 2))
;div使用的是地板除,而/實現的是普通的數學意義上的除法
;這兒不能用/,只能用div
(define (even? n)
(= (double (halve n)) n))
(define (fast-mul-iter n a b)
(cond ((= b 1) (+ n a))
((even? b) (fast-mul-iter n (double a) (halve b)))
(else (fast-mul-iter (+ a n) (double a) (halve b)))))
(define (fast-mul a b)
(if (or (= a 0) (= b 0)) 0 (fast-mul-iter 0 a b)))
《電腦程式的構造與解釋》(五)
抽象的資料是由基本資料型別組合而成。這顯然需要程式語言提供 粘合劑 使得能夠方便的構造抽象資料。是包含兩個元素的復合資料物件。這個元素既可以是基本元素如數字 字母,也可以是另乙個序對。scheme語言中基本過程cons取兩個引數,返回乙個包含這兩個引數作為其成分的復合資料物件 如果給了乙個序對,可以...
《電腦程式的構造與解釋》(七)
define square list ls cond null?ls null else cons car ls car ls square list cdr ls square list是以ls為引數,計算每個元素的平方,然後再構成list並返回。如果需要對list作其他操作,比如開方 加一等呢?...
電腦程式的構造和解釋 練習題1 44
平滑函式的公式為 f s x f x dx f x f x dx 3f s x f x dx f x f x dx 3 fs x f x dx f x f x d x 3他的幾何意義應該是將每個點的導數,變化率變小。說簡單點就是函式那塊曲線彎度比較大,加上這個函式就會減小他的彎度,直到他無限接近於一...