2015-10-08 162 views
0

我想构建一个尾递归过程出我已经构建的另一个过程。但我并没有完全意识到我应该如何思考。我给你两个例子,其中第一个是我的程序,它不是尾递归,第二个是我的“尝试”做一个尾递归过程。是啊...尝试:)我会很高兴的如何构建尾递归程序的任何建议,我应该如何开始,思考和什么。递归过程到尾递归过程

编辑:第一个完全按照我想要的。 (define square (lambda (x) (* x x)))

(do-to-each square '(1 2 3))应方每一个数字,这是榜上无名(1 4 9)


(define do-to-each 
    (lambda (proc lst) 
    (if (list-empty? lst) 
     (list-create) 
      (list-insert (proc (list-first lst)) (do-to-each proc (list-rest lst)))))) 

(define do-to-each-tail 
    (lambda (proc lst) 
    (define loop 
     (lambda (n result) 
     (if (= n 1) 
      (list result) 
      (if (eq? (length result) 1) 
       (car result) 
       (loop (- n 1) (cons (car result) (do-to-each-tail proc (cdr result)))))))) 
    (loop (length lst) lst))) 
+0

相关:http://stackoverflow.com/q/27386520/124319 – coredump

+0

啊谢谢,要去看看那个。 :) – Joel

+0

从列表的尾部开始工作的最简单方法是,结果反过来,然后在基本情况下将结果返回时,再简单地反转结果。 – leppie

回答

2

这是没有必要跟踪长度,索引等的,因为我们可以写一个尾递归解决方案直接迭代输入列表,累积结果并(仅仅为了保持顺序)反转结果。

例如,使用您的符号进行列表操作,这是一个可能的解决方案的样子 - 并注意我们如何将累积结果的初始值称为循环辅助程序,之后我们reverse输出:

(define do-to-each-tail 
    (lambda (proc lst) 
    (define loop 
     (lambda (lst result) 
     (if (list-empty? lst) 
      result 
      (loop (list-rest lst) 
        (list-insert (proc (list-first lst)) result))))) 
    (reverse (loop lst (list-create))))) 

它按预期工作:

(do-to-each-tail square '(1 2 3)) 
=> '(1 4 9)