用于反转列表的Scheme函数

时间:2014-02-27 05:58:17

标签: list scheme reverse

对于我的编程语言类,我应该在Scheme中编写一个函数来反转列表而不使用预制的反向函数。到目前为止,我得到的是

(define (reverseList lst)
(COND
((NULL? lst) '())
(ELSE (CONS (reverseList(CDR lst)) (CAR lst)))
))

我遇到的问题是,如果我输入一个列表,请说(a b c)它会给我(((() . c) . b) . a)

如果没有多组括号和.,我该如何获得干净的清单呢?

4 个答案:

答案 0 :(得分:4)

您的实施问题是cons没有收到列表作为其第二个参数,因此您正在构建的答案不是正确的列表,请记住:a正确的列表由cons带有列表的元素构成,最后一个列表为空。

一种可能的解决方法是使用辅助函数在累加器参数中构建答案,cons反向元素 - 顺便说一下,这个解决方案是尾递归的:

(define (reverse lst)
  (reverse-helper lst '()))

(define (reverse-helper lst acc)
  (if (null? lst)
      acc
      (reverse-helper (cdr lst) (cons (car lst) acc))))

(reverse '(1 2 3 4 5))
=> '(5 4 3 2 1)

答案 1 :(得分:1)

你到了一半。结果中元素的顺序是正确的,只需要修复结构。

您想要的是执行此转换:

 (((() . c) . b) . a)           ; input
 --------------------
 (((() . c) . b) . a)   ()      ; trans-
  ((() . c) . b)       (a)      ;      for-
   (() . c)          (b a)      ;         mation
    ()             (c b a)      ;               steps
      --------------------
                   (c b a)      ;               result

这很容易编码。我们可以立即获得临时值的carcdr。在每个步骤中,下一个中间结果由(cons (cdr interim-value) interim-result)构建,interim-result作为空列表启动,因为这是我们在此构建的 - 列表:< / p>

(define (transform-rev input)
   (let step  ( (interim-value    input)       ; initial set-up of 
                (interim-result    '() ) )     ;  the two loop variables
     (if (null? interim-value)
       interim-result                  ; return it in the end, or else
       (step  (car interim-value)      ; go on with the next interim value
              (cons                    ;      and the next interim result
                  (... what goes here? ...)
                  interim-result )))))

interim-result充当累加器。这就是所谓的“累加器技术”。 step表示使用“named-let”语法编码的循环步骤。

所以总体反向是

(define (my-reverse lst)
   (transform-rev 
       (reverseList lst)))

您是否可以调整transform-rev以便能够接受原始列表作为输入,从而跳过reverseList来电?您只需要更改数据访问部分,即如何获得下一个临时值,以及添加到中间结果中的内容。

答案 2 :(得分:1)

逐步浏览列表并继续将列表的汽车附加到递归调用。

(define (reverseList lst)
(COND
((NULL? lst) '())
(ELSE (APPEND (reverseList(CDR lst)) (LIST (CAR      lst))))
))

答案 3 :(得分:0)

(define (my-reverse L)
 (fold cons '() L)) ;;left fold