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
不是更好吗?