球拍附加不希望的名单逆转

时间:2015-09-02 22:53:37

标签: scheme racket

我写了一个小函数,它接受一个列表并返回一个仅由正数组成的列表。这一切都很好,但由于某种原因,它正在扭转秩序。下面有关于此的更多信息。有人可以告诉我这是否正常,或者我是否错过了什么?提前谢谢。

(define (positive-nums-only lst)
  (if (empty? lst)
      '()
      (append (positive-nums-only (cdr lst))
              (if (>= (car lst) 0)
                  (list (car lst))
                  '()))))
(positive-nums-only '(1 2 -4 90 -4))

上述测试用例返回'(90 2 1)

2 个答案:

答案 0 :(得分:3)

你没有犯错,程序正在制作你所要求的。

请参阅,在进入if语句解析之前,程序首先完成递归调用。这会导致(list ... )从最后一个积极的元素开始列出,在此示例中它将是90

更改代码顺序将产生您想要的结果。

(define (positive-nums-only lst)
(if (empty? lst) '()
  (append (if (>= (car lst) 0 )
             (list (car lst))
             '())
          (positive-nums-only (cdr lst)))
)
)

另一方面,这种递归对于计算机来说可能是昂贵的。我会使用尾递归,如下所示:

  (define positive-nums-only-tail
  (λ (lst r)
    (cond ((empty? lst) (reverse r))
          ((positive? (car lst))
           (positive-nums-only-tail (cdr lst)
                                    (cons (car lst) r)))
          (else (positive-nums-only-tail (cdr lst) r))
          )
    )
  )

答案 1 :(得分:1)

您是否尝试过撤消追加?

(define (positive-nums-only lst)
  (if (empty? lst)
      '()
      (append (if (>= (car lst) 0) (list (car lst)) '())
              (positive-nums-only (cdr lst)))))

就我个人而言,我觉得写这样更自然:

(define (positive-nums-only lst)
  (if (empty? lst)
      '()
      (let ((rest (positive-nums-only (cdr lst))))
        (if (>= (car lst) 0)
            (cons (car lst) rest)
            rest))))