Scheme 球拍附加不希望的列表反转

Scheme 球拍附加不希望的列表反转,scheme,racket,Scheme,Racket,我编写了一个小函数,它接受一个列表并返回一个仅由正数组成的列表。这一切都很好,但出于某种原因,它正在颠倒顺序。更多信息如下。有人能告诉我这是否正常,或者我是否错过了一些东西?先谢谢你 (define (positive-nums-only lst) (if (empty? lst) '() (append (positive-nums-only (cdr lst)) (if (>= (car lst) 0)

我编写了一个小函数,它接受一个列表并返回一个仅由正数组成的列表。这一切都很好,但出于某种原因,它正在颠倒顺序。更多信息如下。有人能告诉我这是否正常,或者我是否错过了一些东西?先谢谢你

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

您是否尝试反转追加

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

你没有犯错误,程序正在按你的要求进行

请参阅,程序首先完成递归调用,然后再解析
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))
          )
    )
  )

@aurora91没问题,请参见使用
let
cons
的另一种编辑方式谢谢,我一定会测试它并使用它!非常感谢您分享尾部递归解决方案!今天的课上我们刚刚讲过,所以这将是我以后作业的一个很好的参考
(追加x y)
x
放在
y
前面,不管先计算哪个。@Molbdnilo是的,这就是为什么它会添加正在计算的元素,如果它通过槽,而不是将其保留到递归完成为止。@DavidMerinos很抱歉,但我不知道你的意思。听起来好像您认为
(if(>=(car lst)0)(list(car lst))())的值取决于递归调用是在它之前还是之后进行计算,但这与您的同意相矛盾。
(foldr cons(list(car lst))r)
在每次迭代中都会通过并生成一个新的列表。我打赌它可能比
append
慢。在前面做一个
cons
,在最后做一个
reverse
不是更好吗?