Scheme作业递归问题求助:累加和函数与计数函数
解决Scheme递归函数的两个问题:累加和列表与元素计数
一、实现summer(累加和列表)函数
先理清楚这个函数的核心需求:输入一个数字列表,返回每个位置的累加和组成的新列表,比如(summer '(1 2 3))要得到(1 3 6)。
递归的关键在于传递当前的累加值——因为每一步的结果都依赖于前面所有元素的总和。咱们可以用带辅助参数的递归函数来实现,逻辑会非常清晰:
(define (summer lst) ; 定义辅助函数,参数是剩余待处理的列表和当前累计的和 (define (helper remaining current-sum) (if (null? remaining) '() ; 空列表直接返回空,触发递归终止 (cons (+ (car remaining) current-sum) ; 计算当前元素的累加值并加入结果 (helper (cdr remaining) (+ (car remaining) current-sum))))) ; 递归处理剩余列表,同时更新累计和 (helper lst 0)) ; 初始调用时,累计和从0开始
咱们走一遍示例的执行过程,帮你理解递归逻辑:
- 初始调用
(helper '(1 2 3) 0):返回(cons 1 (helper '(2 3) 1)) - 下一步
(helper '(2 3) 1):返回(cons 3 (helper '(3) 3)) - 再下一步
(helper '(3) 3):返回(cons 6 (helper '() 6)) - 最后
(helper '() 6)返回'(),最终拼接出结果(1 3 6),完全符合需求!
如果你不想用辅助函数,也可以通过递归返回值推导(虽然效率稍低,但也是一种思路):
(define (summer lst) (if (null? lst) '() (let ((first (car lst)) (rest-sums (summer (cdr lst)))) (cons first (map (lambda (x) (+ x first)) rest-sums)))))
二、实现统计元素出现次数的递归函数
假设函数名叫count-occurrences,输入是目标元素和列表,返回该元素在列表中出现的次数。递归思路非常直观:
- 终止条件:如果列表为空,直接返回0(没有元素可统计)。
- 递归步骤:
- 如果列表的第一个元素等于目标元素,结果就是
1 + 剩余列表的统计结果; - 如果不等于,结果就是
剩余列表的统计结果。
- 如果列表的第一个元素等于目标元素,结果就是
这里注意判断元素相等的函数:通用场景下用equal?(能处理字符串、列表等复杂类型)更稳妥,代码如下:
(define (count-occurrences target lst) (if (null? lst) 0 (if (equal? (car lst) target) (+ 1 (count-occurrences target (cdr lst))) (count-occurrences target (cdr lst)))))
测试一下:(count-occurrences 'a '(a b a c a))会返回3,完美匹配预期。
如果需要处理嵌套列表(比如统计(a (b a) c)中a的次数),只需要加一步判断,递归处理子列表即可:
(define (count-occurrences target lst) (cond ((null? lst) 0) ((list? (car lst)) (+ (count-occurrences target (car lst)) (count-occurrences target (cdr lst)))) ((equal? (car lst) target) (+ 1 (count-occurrences target (cdr lst)))) (else (count-occurrences target (cdr lst)))))
调用(count-occurrences 'a '(a (b a) c))会返回2,符合嵌套场景的需求。
内容的提问来源于stack exchange,提问作者nwelch
相关产品推荐
相关产品推荐

