【发布时间】:2020-12-09 12:45:00
【问题描述】:
(define (oddrev ls)
(cond ((null? ls) ls)
((null? (cdr ls)) ls)
(else (cons (car ls) (oddrev (cdr (cdr ls)))))))
我有一个返回奇数数组元素的方案,但我想在最后反转列表。 我该怎么做??
【问题讨论】:
(define (oddrev ls)
(cond ((null? ls) ls)
((null? (cdr ls)) ls)
(else (cons (car ls) (oddrev (cdr (cdr ls)))))))
我有一个返回奇数数组元素的方案,但我想在最后反转列表。 我该怎么做??
【问题讨论】:
简单的解决方案是添加一层间接:
(define (oddrev-helper ls)
(cond ((null? ls) ls)
((null? (cdr ls)) ls)
(else (cons (car ls) (oddrev-helper (cdr (cdr ls)))))))
(define (oddrev ls) (reverse (oddrev-helper ls)))
这看起来很浪费,但比在末尾重复附加一个单例列表要高效得多。
但是,如果您遇到过通过累加器和尾递归将递归过程转换为迭代的方法,您会注意到列表过程有逆向产生结果的习惯。
如果您确实想要反向结果,您可以利用这一点。
(define (oddrev-helper ls acc)
(cond ((null? ls) acc)
((null? (cdr ls)) (cons (car ls) acc))
(else (oddrev-helper (cdr (cdr ls)) (cons (car ls) acc)))))
(define (oddrev ls) (oddrev-helper ls '()))
【讨论】:
通过尾递归(返回时省略通常的reverseing。
(define (oddrev ls (acc '()))
(cond ((or (null? ls) (null? (cdr ls))) acc)
(else (oddrev (cdr (cdr ls)) (cons (car ls) acc)))))
或者通过标准的高阶函数:
(define (oddrev ls)
(reverse (filter odd? ls)))
试用:
(oddrev '(1 2 3 4 5 6))
;; '(5 3 1)
换行
(cond ((or (null? ls) (null? (cdr ls))) acc)
到:
(cond ((or (null? ls) (null? (cdr ls))) (reverse acc))
让它按输入顺序返回:'(1 3 5)
【讨论】: