如果创建一个chez scheme 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?
答案 0 :(得分:4)
我想你可能想稍微概括一下,所以我做了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)))))
现在这种带尾递归和累加器的循环可以转换为折叠。您可以在SRFI-1 list library找到折叠:
(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
,它甚至可能变得更快,但您正在限制列表的长度。 (许多方案系统在有限大小的堆栈上推送参数,而折叠将在当时累积列表中的一个元素。)
答案 1 :(得分:2)
使用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)
答案 2 :(得分:2)
一般技术是首先形成您要处理的元素列表。你已经有这个清单了。然后,您要将一个或多个转换应用于输入列表。在这种情况下,我们不需要进行任何转换。然后,过滤列表以仅获取满足特定条件的元素。最后,应用组合筛选列表中元素的操作。
这种处理列表的一般方法在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的条件。
答案 3 :(得分:1)
添加一个函数,通过过滤掉不大于10的数字来返回列表。将其返回值传递给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))))
答案 4 :(得分:1)
如果你想保留一个通用的suma
,而不是定义一个包含过滤器的suma,你可以改为定义一个只是求和的suma,然后在将它作为参数传递时过滤你的列表: / p>
(define elems (list 2 4 1 12 32 3 34 12))
(define (suma lst)
(apply + lst))
(suma (filter (lambda (x) (> x 10)) elems))
现在您已经获得了广义sum
,并且只传递了您想要求和的原始列表部分。