2010-07-09 172 views
1

我一直試圖通過教程如何設計計劃的程序來學習一些編程。直到現在我已經完成了所有的事情。問題如下:計劃:遞歸和列表

9.5.5開發函數convert。它消耗一個數字列表,並且 產生相應的數字。 的第一個數字是最不重要的, 依此類推。

繼前幾個步驟,從數據分析,模板,我最終 了這一點,一個程序的梗概:

;; A list-of-numbers is either 1. an empty list, empty, or 2. (cons n 
lon) where n is a number and lon is a list of numbers 
;; convert : lon -> number 
;; to consume a lon and produce the corresponding number. The least 
significant digit corresponds to the first number in the list, and so 
on. 
;; (= (convert (cons 1 (cons 9 (cons 10 (cons 99 empty))))) 991091) 
(define (convert lon) 
    (cond 
    [(empty? lon)...] 
    [(cons? lon)...(first lon)...(convert (rest lon))...])) 

如何突破這個階段,作爲書有它,「結合價值」? 單向我認爲可以工作是,如果我乘以所述第一值通過 10的總數的值的意義,例如,功率,

(利弊1(利弊9空))=> 1 * 10 ^(SIGNIFICANCE),其中至少 顯着性爲0.使用我對 編程的有限理解,我認爲需要一些計數器,其中n每次增加 一次,以一種說法的方式遞歸地稱爲 。但是在我看來,這是試圖同時運行兩個遞歸的 。因爲表達式按順序(顯然)被評估爲 ,所以當您調用convert函數時,不能調用計數器函數。

那麼,誰能幫我解決這個問題?如果你用 解決了這個問題,那麼使用自然遞歸和列表的CONSUTRUCTOR來解決這個問題,而不是使用lambda或本書尚未解決的其他想法。

謝謝!

回答

0

你不需要做指數運算 - 簡單的乘法運算就可以。

(define (convert digits) 
    (cond 
    ((empty? digits) 0) 
    (else (+ (* 10 (convert (rest digits))) (first digits))) 
) 
) 

(convert '(1 2 3 4 5 6)) 

或者,思考它的另一種方式:

(define (convert digits) 
    (convert-helper digits 1 0) 
) 

(define (convert-helper digits multiplier sofar) 
    (cond 
    ((empty? digits) sofar) 
    (else 
     (convert-helper 
      (rest digits) 
      (* 10 multiplier) 
      (+ (* multiplier (first digits)) sofar) 
     ) 
    ) 
) 
) 


(convert '(1 2 3 4 5 6)) 
+1

+1不使用求冪,-1代碼格式化。 – danlei 2010-07-09 01:00:57

+0

哇!謝謝!通過步進器,我意識到我錯過了什麼:(首先是非空列表)會在遞歸調用函數時「持有」表達式中的值。出於某種原因,我不認爲這是可能的。 無論如何,謝謝! – 2010-07-09 01:17:33

+0

@danlei - 我知道這不是lisp-y語言的常規格式,但我個人發現它很容易遵循。查看哪些括號對我來說比保存幾行更有用。我不是一個功能強大的程序員,所以我用我的開幕式和閉幕式排隊。 – 2010-07-09 01:59:20

0

下面是一個尾遞歸版本:

(define (convert lon) 
    (let rec ((i 0) 
      (n 0) 
      (lon lon)) 
    (cond ((empty? lon) n) 
      (else (rec (+ i 1) 
        (+ n (* (first lon) (expt 10 i))) 
        (rest lon)))))) 
+0

感謝您的意見!但是我恐怕沒有涉及到關於let的書的部分,所以我對它的作用一無所知。 – 2010-07-09 01:21:51

+0

不客氣。至於讓步:它用於綁定變量。在我的回答中,我用了一個名爲let的名字;一個構造,這對於遞歸非常方便。另外,考慮接受詹姆斯或我的答案,無論哪一個對你最有幫助。 – danlei 2010-07-09 01:30:56

+0

我剛剛意識到傑米黃的是行不通的,如果在列表中的數大於9所以(1缺點(缺點9(利弊10(99利弊空))))=> 100091,未991091.當然,我認爲他實際上理解了作者的意圖,而我認爲「數字」(0-9)可以是任何整數。我敢打賭,你的做我的想法,但我不知道如何處理「讓」構造發現。 – 2010-07-09 18:25:23