反向清单 - 计划

时间:2013-02-25 00:07:19

标签: scheme racket

我正在尝试撤消列表,这是我的代码:

(define (reverse list)
  (if (null? list) 
     list
      (list (reverse (cdr list)) (car list))))

所以,如果我输入(反向'(1 2 3 4)),我希望它出来(4 3 2 1),但现在它不给我那个。我做错了什么,我该如何解决?

9 个答案:

答案 0 :(得分:13)

重复列表的自然方式不是解决此问题的最佳方法。使用append,正如@lancery指出的接受的答案中所建议的那样,也不是一个好主意 - 无论如何,如果你在Scheme中学习你的方式,那么如果你试图自己实现解决方案,我会告诉你该做什么,但首先是一个提示 - 不要使用list作为参数名称,这是一个内置程序,你将覆盖它。使用其他名称,例如lst

通过辅助程序反转列表更简单,该程序累积了结果的 head 中每个元素的结果,这将产生反转列表的效果 - 顺便提一下,辅助程序是尾递归的。这是一般的想法,填补空白:

(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,因此有一个内置的procedure

答案 1 :(得分:2)

使用名为let的尾递归方法:

(define (reverse lst)
  (let loop ([lst lst] [lst-reversed '()])
    (if (empty? lst)
        lst-reversed
        (loop (rest lst) (cons (first lst) lst-reversed)))))

这与在Oscar的答案中使用带有累加器参数的辅助函数的方法基本相同,其中loop之后的let绑定使得let成为内部函数,你可以调用

答案 2 :(得分:2)

这是一个递归过程,它描述了在Scheme中反转列表的迭代过程(尾递归)

(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)

这是一个递归过程,描述了在Scheme中反转列表的递归过程(不是尾递归)

(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(list 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)

答案 3 :(得分:0)

以下是使用build-list程序的解决方案:

(define reverse
  (lambda (l)
    (let ((len (length l)))
      (build-list len
                  (lambda (i)
                    (list-ref l (- len i 1)))))))

答案 4 :(得分:0)

这个有效,但它不是尾递归过程:

(define (rev lst)
 (if (null? lst)
     '()
      (append (rev (cdr lst)) (car lst))))

答案 5 :(得分:0)

我认为最好使用append代替cons

(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 '())
)

答案 6 :(得分:0)

尾递归解决方案:

(define (reverse oldlist)
    (define (t-reverse oldlist newlist)
        (if (null? oldlist)
            newlist
            (t-reverse (cdr oldlist) (cons (car oldlist) newest))))
    (t-reverse oldlist '()))

答案 7 :(得分:-1)

(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) )

另一个与奥斯卡相似的答案。我刚开始学习计划,请原谅我,以防你发现问题:)。

答案 8 :(得分:-1)

实际上没有必要用一堆lambda追加或填充身体。

(define (reverse items)
  (if (null? items)
      '()
      (cons (reverse (cdr items)) (car items))))