我试图扭转一个列表,这里是我的代码:
(define (reverse list)
(if (null? list)
list
(list (reverse (cdr list)) (car list))))
所以,如果我进入(反“(1 2 3 4)),我希望它出来为(4 3 2 1),但现在它不给我说。 我在做什么错了,我该如何解决?
我试图扭转一个列表,这里是我的代码:
(define (reverse list)
(if (null? list)
list
(list (reverse (cdr list)) (car list))))
所以,如果我进入(反“(1 2 3 4)),我希望它出来为(4 3 2 1),但现在它不给我说。 我在做什么错了,我该如何解决?
复发在列表中的自然的方式是不是解决这个问题的最好办法。 使用append
,如在由@lancery指出接受的答案建议,是不是一个好主意,要么-反正如果你正在学习用自己的方式在方案,如果你尝试自己实施该解决方案是最好的,我会告诉你什么这样做,但首先一个提示-不使用list
作为参数的名字,这是一个内置的程序,你会覆盖它。 使用其他名称,比方说, lst
。
这是简单的逆转,其累积consing的结果,在结果的头上,每种元素的辅助程序的方式列表,这将有扭转名单的影响-顺便说一句,助手程序是尾递归。 这里的总体思路,填充了空白:
(define (reverse lst)
(<???> lst '())) ; call the helper procedure
(define (reverse-aux lst acc)
(if <???> ; if the list is empty
<???> ; return the accumulator
(reverse-aux <???> ; advance the recursion over the list
(cons <???> <???>)))) ; cons current element with accumulator
当然,在现实生活中你就不会实现reverse
从无到有,有一个内置的程序为。
使用一个名为尾递归方法let
:
(define (reverse lst)
(let loop ([lst lst] [lst-reversed '()])
(if (empty? lst)
lst-reversed
(loop (rest lst) (cons (first lst) lst-reversed)))))
这是基本相同的方法具有在奥斯卡的答案,其中与蓄能器参数的辅助功能loop
后结合let
让让进一个内部函数可以调用。
这里是描述反转方案的列表的迭代过程(尾递归)递归过程
(define (reverse lst)
(define (go lst tail)
(if (null? lst) tail
(go (cdr lst) (cons (car lst) tail))))
(go lst ())))
使用替换模型(反向(列表1 2 3 4))
;; (reverse (list 1 2 3 4))
;; (go (list 1 2 3 4) ())
;; (go (list 2 3 4) (list 1))
;; (go (list 3 4) (list 2 1))
;; (go (list 4) (list 3 2 1))
;; (go () (list 4 3 2 1))
;; (list 4 3 2 1)
这里是描述扭转计划列表的递归过程(不是尾递归)递归过程
(define (reverse2 lst)
(if (null? lst) ()
(append (reverse2 (cdr lst)) (list (car lst)))))
(define (append l1 l2)
(if (null? l1) l2
(cons (car l1) (append (cdr l1) l2))))
使用替换模型(reverse2(列表1 2 3 4))
;; (reverse2 (list 1 2 3 4))
;; (append (reverse2 (list 2 3 4)) (list 1))
;; (append (append (reverse2 (list 3 4)) (list 2)) (list 1))
;; (append (append (append (reverse2 (list 4)) (list 3)) (list 2)) (list 1))
;; (append (append (append (append (reverse2 ()) (list 4)) (list 3)) (list 2)) (list 1))
;; (append (append (append (append () (list 4)) (list 3)) (list 2)) (list 1))
;; (append (append (append (list 4) (list 3)) (list 2)) (list 1))
;; (append (append (list 4 3) (list 2)) (list 1))
;; (append (list 4 3 2) (list 1))
;; (list 4 3 2 1)
下面是一个使用解决方案build-list
程序:
(define reverse
(lambda (l)
(let ((len (length l)))
(build-list len
(lambda (i)
(list-ref l (- len i 1)))))))
这一个工作,但它不是一个尾递归过程:
(define (rev lst)
(if (null? lst)
'()
(append (rev (cdr lst)) (car lst))))
我认为这将是更好地使用,而不是追加的利弊
(define (myrev l)
(if (null? l)
'()
(append (myrev (cdr l)) (list (car l)))
)
)
这另一个版本与尾递归
(define (myrev2 l)
(define (loop l acc)
(if (null? l)
acc
(loop (cdr l) (append (list (car l)) acc ))
)
)
(loop l '())
)
(define reverse?
(lambda (l)
(define reverse-aux?
(lambda (l col)
(cond
((null? l) (col ))
(else
(reverse-aux? (cdr l)
(lambda ()
(cons (car l) (col))))))))
(reverse-aux? l (lambda () (quote ())))))
(reverse? '(1 2 3 4) )
还有一个答案类似奥斯卡。 我刚开始学习方案,所以原谅我的情况下,你会发现问题:)。
实际上,有没有必要追加或与一群lambda表达式的填充体。
(define (reverse items)
(if (null? items)
'()
(cons (reverse (cdr items)) (car items))))