Scheme中的递归问题

时间:2014-12-17 00:22:48

标签: recursion scheme

以下代码:

(define (rcons val lst)
    (if (not (null? lst))
        (cons (car lst) (rcons val (cdr lst)))
        (cons lst (list val)))))

(rcons 'E '(A B C D))

应生成(A B C D E),而是提供(A B C D () E)

的结果

我的递归步骤有什么问题?

2 个答案:

答案 0 :(得分:2)

我不能在本地运行它,但你应该在最后的递归中返回列表的末尾(而不是像你想要的那样返回整个列表,顺便说一下,它总是为空... ):

(define (rcons val lst)
    (if (not (null? lst))
        (cons (car lst) (rcons val (cdr lst)))
        (cons val '()))) ; recursion ends here - only return end of list cons

记住正确的列表以null结尾('())。

列表结构:

如果你想到递归展开,你会得到什么(看看最后 cons):

(cons #1 (cons #2 (cons #3 (cons .... (cons val '()))))

#1#2#3等描述了原始lst的成员以及帧编号(1是第一个)。

更多可视化 - 递归展开:

; {x} - x marks frame as well as location in original 'lst'
; frame 1
(cons (car lst {1}) (rcons val (cdr lst)))
; frame 2
(cons (car lst {1}) (cons (car lst {2}) (rcons val (cdr lst))))
; frame 3 ...
(cons (car lst {1}) (cons (car lst {2}) (cons (car lst {3}) (rcons val (cdr lst)))))

如果您回顾列表结构,我们很容易看到我们希望val成为最后car的{​​{1}},{{1成为cons - 形成一个正确的列表。这是完全我在您的代码中修复的内容。

答案 1 :(得分:0)

你真是太近了!

列表结构从头到尾迭代,并从头到尾构建。如果您要制作列表(1 2 3),首先必须(2 3),然后cons第一个1到完成的构建列表(2 3)。您的rcons按照(cons (car lst) (rcons val (cdr lst)))的说法执行此操作,该列表会将当前值列表列表的其余部分rcons。在评估两个表达式之后完成cons。因此对于3元素列表,它将递归3次。 (cons first-value (cons second-value (cons third-value (rcons val-value '()))))

因此,如果val为4 (rcons 4 '())应生成(cons 4 '())(list 4),则相同。这应该很好用。

(define (rcons val lst)
    (if (not (null? lst))
        (cons (car lst) (rcons val (cdr lst)))
        (list val)))

(rcons 4 '())      ; ==> (4)
(rcons 4 '(1 2 3)) ; ==> (1 2 3 4)