有在你的代碼幾次失誤,對於初學者來說,你不需要在let
定義一個全局變量存儲結果,它的當你在遞歸中前進時足以構建答案。在這種情況下不要使用append
,如果嚴格遵循解決方案模板,cons
就足以構建輸出列表。
你應該堅持遞歸構建一個新列表的方法;這是怎樣的問題應該使用的配方來解決,這或許更多的慣用這樣的:
(define preplist
(lambda (x y)
(cond ((> x y) ; if the exit condition is met
empty) ; then return the empty list
(else ; otherwise
(cons x ; cons the current element
(preplist (add1 x) y)))))) ; and advance the recursion
一個完全不同的方法是寫一個尾遞歸的解決方案。這是更高效的,因爲使用了恆定數量的堆棧。它並不遵循上面所述的設計方法,但與您想到的解決方案稍微相似 - 但請記住,這不使用全局變量(迭代中只有一個名爲let
),解決方案是積累和周圍作爲參數傳遞:設置你會使用
(define (preplist x y)
(let loop ((i y) ; named let for iteration
(acc empty)) ; define and initialize parameters
(if (> x i) ; if exit condition is met
acc ; return accumulated value
(loop (sub1 i) ; otherwise advance recursion
(cons i acc))))) ; and add to the accumulator
當然,在評論中指出的@dyoo,在實際內置range
的過程,它確實基本相同preplist
程序。
附註:這是一個在Racket中的內置程序:它被稱爲'range'。 http://docs.racket-lang.org/reference/pairs.html#%28def._%28%28lib._racket%2Flist..rkt%29._range%29%29 – dyoo 2013-03-19 06:59:02