编写递归Scheme函数:提取列表奇数位元素并逆序返回
嘿,我完全懂你的需求——你想要一个纯递归的Scheme函数,不依赖任何现成的odd或者reverse工具函数,直接一步到位提取列表里的奇数位元素,还得以逆序返回对吧?其实我们可以把两个操作的逻辑合并到同一个递归过程里,不用分开写然后组合。
核心思路
在递归遍历的时候,先处理后面的奇数位元素,再把当前的奇数位元素追加到结果的末尾,这样自然就完成了逆序。因为递归会先深入到列表的最后一个奇数位元素,然后层层返回时把前面的元素依次加在后面,最终得到逆序的奇数位列表。
基础实现(纯自递归,无辅助函数)
话不多说,直接上符合你要求的代码:
(define (reverse-odd lst) (cond ((null? lst) '()) ((null? (cdr lst)) (list (car lst))) (else (append (reverse-odd (cddr lst)) (list (car lst))))))
测试验证
我们来跑几个例子确认效果:
- 输入
'(1 2 3 4 5),输出'(5 3 1)(正确提取奇数位并逆序) - 输入
'(a b c d),输出'(c a)(符合预期) - 输入
'(x),输出'(x)(单元素列表直接返回) - 输入
'(),输出'()(空列表边界处理正确)
递归逻辑拆解
- 终止条件1:如果列表是空的,直接返回空列表,这是递归的边界。
- 终止条件2:如果列表只有一个元素,那它肯定是奇数位(第1位),逆序就是它自己,所以返回包含这个元素的列表。
- 递归步骤:当列表长度≥2时,我们跳过第二个元素(用
cddr lst直接取从第三个元素开始的子列表),先递归处理这个子列表的奇数位逆序,然后把当前列表的第一个元素(也就是当前的奇数位元素)包装成列表,追加到递归结果的后面。每一层递归都会把当前的奇数位元素放到后面,最终形成逆序结果。
优化版(高效无append)
上面的基础版用了append,对于长列表效率会稍低(因为append需要遍历整个列表)。如果允许用内部辅助函数(依然是自身定义的,不算调用外部函数),可以用cons直接构建结果,效率更高:
(define (reverse-odd lst) (define (helper current result) (cond ((null? current) result) ((null? (cdr current)) (cons (car current) result)) (else (helper (cddr current) (cons (car current) result))))) (helper lst '()))
这个版本里,helper遍历列表时遇到奇数位元素就用cons加到结果的前面,最终直接得到逆序的奇数位列表,性能更优。
内容的提问来源于stack exchange,提问作者Arsh Ballagan
相关产品推荐
相关产品推荐

