這道練習的中文版翻譯有誤,原文是『...write a procedure that computes elements of pascal』s ******** by means of a recursive process.』,譯文只翻譯了『。。。它採用遞迴計算過程計算出帕斯卡三角形。』,這裡應該是『帕斯卡三角形的各個元素』才對。
在sicp解題集中,作者分別展示了用遞迴計算過程和迭代計算過程來求出乙個值的過程,該值是帕斯卡三角形第row行的第col個元素的數值,過程接收row和col兩個引數。
我自己的想法是,我希望寫出乙個過程,它接收乙個正整數,求值出乙個n個元素的表,表的第x(1 <= x <= n)個元素是帕斯卡三角形第x層的元素表。
於是我首先define乙個過程,把它命名為pasika(沒錯,就是帕斯卡的拼音哈哈),它接收形參n,求值出1~n層的帕斯卡三角形,並將它們按遞增順序裝入乙個表中。
為了實現它,我用「按願望思維」的策略。
我先假定有那麼乙個中間過程pasika-n-list,它接收形參n,求值出帕斯卡三角形的第n層的所有數值,並組成乙個表;
然後我又假定有乙個過程pasika-list,它接收形參a和b,返回帕斯卡三角形從a層到b層元素表的表。如此一來過程pasika就可以這樣定義:
(define (pasika n)
(pasika-list 1 n))
然後pasika-list過程也可以這樣定義:
(define (pasika-list a b)
(if (or (< a b) (= a b))
(cons (pasika-n-list a) (pasika-list (+ 1 a) b))
nil))
其含義是,如果引數a接下來考慮pasika-n-list的實現,同樣「按願望思維」,
假定有個過程pasika-n-list-recursive,它接收引數s和乙個表before-list,表before-list代表上一層的表,該過程返回乙個before-list下一層所有元素的表,s是乙個計數器,當s為0時該過程返回nil充當表尾,其他情況則是用於組合起該層第s個元素;
然後再假定乙個過程nlist-recursive,它相似的接收乙個引數a和乙個表before-list,返回第n層的第a個元素,可以把它定義在pasika-n-list裡面,這樣它的引數n就對nlist-recursive是自由變數(「詞法作用域」)。
現在的問題在於,如何知道帕斯卡三角形任意一層的任意乙個元素的數值呢?
我們知道帕斯卡三角形每一層的第乙個和最後乙個元素的數值是1,其他數值則是其上一層對應元素和之前乙個元素的和。
於是我們可以假定有個過程no. ,它接收乙個表llist和引數k,求值出表llist的第k個元素,這樣就可以定義過程nlist-recursive:
(define (nlist-recursive a before-list)
(if (or (= a 1) (= a n))
1(+ (no. before-list (- a 1))
(no. before-list a))))
no.過程可以直接定義:(define (no. llist k)
(cond ((null? llist) nil)
((= k 1) (car llist))
(else (no. (cdr llist) (- k 1)))))
接下來pasika-n-list-recursive也可以這樣定義了:
(define (pasika-n-list-recursive s before-list)
(cond ((= s 0) nil)
(else (cons (nlist-recursive s before-list)
(pasika-n-list-recursive (- s 1) before-list)))))
最後,定義pasika-n-list如下:
(define (pasika-n-list n)
(cond ((= n 1) (list 1))
((= n 2) (list 1 1))
(else (pasika-n-list-recursive n (pasika-n-list (- n 1))))))
把**整合一下,整體就出來了。
(define (pasika n)
(define (pasika-n-list n)
(define (no. llist k)
(cond ((null? llist) nil)
((= k 1) (car llist))
(else (no. (cdr llist) (- k 1)))))
(define (nlist-recursive a before-list)
(if (or (= a 1) (= a n))
1(+ (no. before-list (- a 1))
(no. before-list a))))
(define (pasika-n-list-recursive s before-list)
(cond ((= s 0) nil)
(else (cons (nlist-recursive s before-list)
(pasika-n-list-recursive (- s 1) before-list)))))
(cond ((= n 1) (list 1))
((= n 2) (list 1 1))
(else (pasika-n-list-recursive n (pasika-n-list (- n 1))))))
(define (pasika-list a b)
(if (or (< a b) (= a b))
(cons (pasika-n-list a) (pasika-list (+ 1 a) b))
nil))
(pasika-list 1 n))
在racket上執行一下,效果如圖
sicp練習1 12 帕斯卡三角(楊輝三角)
楊輝三角以前在學習c語言時候,用迴圈很容易實現。由於剛剛接觸函式式語言,遞迴和迭代方式實現迴圈還沒深入我心。下意思的想用鍊錶來實現,但發現自己對scheme的鍊錶操作太不熟悉,總會出現這樣那樣子的無法自我解釋的問題。最後參考了 dennis zane 的pascal實現,dennis zane 是把...
初識yii1 1 2 生成乙個搜尋框
我負責的是乙個客戶模組,要在管理客戶的頁面 views customers admin.php 實現乙個搜尋框,根據輸入的關鍵字查詢含有該關鍵字的所有記錄並在該頁顯示。其實在用gii生成crud時,yii已經在admin.php為我們提供了乙個 advanced srarch 按鈕,參照這個功能的實...
練習2 17 生成3的乘方表
輸入乙個非負整數n,生成一張3的乘方表,輸出3 0 3 n 的值。可呼叫冪函式計算3的乘方。輸入在一行中給出乙個非負整數n。按照冪的遞增順序輸出n 1行,每行格式為 pow 3,i 3的i次冪的值 題目保證輸出資料不超過長整型整數的範圍。3pow 3,0 1 pow 3,1 3 pow 3,2 9 ...