如果创建一个chez方案ex,使lista_de_elemente中的所有元素相加
(define lista_de_elemente (list 2 4 1 12 32 3 34 12))
(define suma
(lambda()
(apply + lista_de_elemente)))
如何使仅元素的总和大于10?
我想你可能想对它进行一点概括,所以我制作了filter-sum
,这样你就可以做到这一点:
#!r7rs ; #!r6rs for r6rs
(import (scheme) ; replace scheme with rnrs for r6rs
(only (srfi :1) filter fold)) ; remove filter for r6rs
;; I renamed you list
(define *lista-de-elemente* '(2 4 8 10 12 14 16))
(define (suma)
(define (>10? x)
(> x 10))
(filter-sum >10? *lista-de-elemente*))
(suma) ; ==> 42
以下是filter-sum
的一些可能版本。我们有直接的递归方式:
(define (filter-sum predicate lst)
(cond ((null? lst) 0)
((not (predicate (car lst))) (filter-sum predicate (cdr lst)))
(else (+ (car lst) (filter-sum predicate (cdr lst))))))
但这不是很好,因为顺序或数字并不重要。我们可以用一个累加器递归地完成这个尾部,这里用一个名为let
的程序,而不是一个腋窝程序:
(define (filter-sum predicate lst)
(let loop ((lst lst)(acc 0))
(if (null? lst)
acc
(loop (cdr lst)
(if (predicate (car lst))
(+ acc (car lst))
acc)))))
现在,这种带有尾部递归和累加器的循环可以转换为fold。您可以在SRFI-1列表库中找到折叠:
(define (filter-sum predicate lst)
(fold (lambda (x acc)
(if (predicate x)
(+ acc x)
acc))
0
lst))
现在的大部分代码是您是否应该添加。使用filter
,您可以过滤掉,以便可以添加折叠中的每个元素:
(define (filter-sum predicate lst)
(fold + 0 (filter predicate lst)))
filter
也在SRFI-1列表库中。现在,如果你知道你列出的10以上的数字很短。。像几百个一样,您可以将fold
完全更改为apply
,甚至可能会变得更快,但您对列表的长度进行了限制。(许多方案系统在有限大小的堆栈上推送参数,而折叠会一次累积列表中的一个元素。(
一般技术是首先形成要处理的元素列表。您已拥有此列表。然后,您希望对输入列表应用一个或多个转换。在这种情况下,我们不需要进行任何转换。然后,过滤列表以只获取满足特定条件的元素。最后,您将应用对筛选列表中的元素进行组合的操作。
这种处理列表的通用方法在SICP中被描述为
enumerate -> transform (map) -> filter -> accumulate
现在,在这种情况下,我们不需要枚举或映射任何内容,因为我们已经有了前面提到的输入列表。
(define (filter predicate sequence) (cond
((null? sequence) '())
(else (cond
((predicate (car sequence)) (cons (car sequence) (filter predicate (cdr sequence))))
(else (filter predicate (cdr sequence)))))))
(define (accumulate op initial sequence) (cond
((null? sequence) initial)
(else (op (car sequence) (accumulate op initial (cdr sequence))))))
(define (sum-list list) (accumulate + 0 (filter (lambda(x) (cond ((> x 10) #t) (else #f)))list)))
(sum-list (list 1 2 3 45 12))
;Output: 57
predicate
只是一个计算结果为true或false的条件。
使用filter
:
(define suma
(lambda()
(apply + (filter (lambda (e) (> e 10)) lista_de_elemente))))
BTW,suma
应该将列表作为参数:
(define suma
(lambda(lst)
(apply + (filter (lambda (e) (> e 10)) lst))))
(suma lista_de_elemente)
apply
。
(define (get-greater-than-ten lst)
(define (helper in out)
(if (null? in)
out
(if (> (car in) 10)
(helper (cdr in) (append out (list (car in))))
(helper (cdr in) out)))
(helper lst `()))
像一样使用
(define suma
(lambda()
(apply + (get-greater-than-ten lista_de_elemente))))
如果你想保留一个广义的suma
,而不是定义一个包含过滤器的suma,你可以定义一个只求和的suma然后在将列表作为参数传递时对其进行过滤:
(define elems (list 2 4 1 12 32 3 34 12))
(define (suma lst)
(apply + lst))
(suma (filter (lambda (x) (> x 10)) elems))
现在,您已经得到了广义sum
,并且只将原始列表中要求和的部分传递给它。