以下代码:
(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)
我的递归步骤有什么问题?
答案 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)