[英]R5RS scheme code find sum of the even elements in a list(recursive and higher order abstractions)?
(define mylist (list 1 2 3 5 8 9 10))
;;sum of the squares of the even elements of mylist
(define (evens lis)
(cond (;; Check stop condition 1
(null? lis)
'())
(;; Check stop condition 2: list of length = 1
(null? (cdr lis))
'())
(else
;; Check: Building list with second element
;; The previous cond clauses have already sorted out
;; that lis and (cdr lis) are not null.
(cons (cadr lis)
;; Check: Recurse "the rest of the rest" of lis with cddr
(evens (cddr lis))))))
(define (sum-even lis)
(if (null? lis)
0
(+ (expt (car lis) 2) (sum-even(cdr lis))))) ;;add all squared even elements
(sum-squared-even (evens mylist))
这是我尝试查找列表中偶数元素的平方和。 但是,我对r5rs真的很陌生, 是否可以将这些方案仅编写到一个过程中? 另外, 还要求我编写有关map,foldr和filter的第二个版本 。 希望任何熟悉r5rs的人都能帮助我! 谢谢!
首先,您的功能是错误的,因为您没有测试列表编号的均匀性。 这应该是正确的定义:
;;even elements of a list
(define (evens lis)
(cond (;; Check stop condition
(null? lis)
'())
(;; Check if first element is even,
;; return it with the evens of the rest of the list
(even? (car lis))
(cons (car lis) (evens (cdr lis))))
(else
;; First element is odd, return only the evens of the rest of the list
(evens (cdr lis)))))
然后,为了回答您的第一个问题,这是一个具有单个递归函数的解决方案:
;;sum of the squares of the even elements of a list
(define (sum-square-evens lis)
(cond ((null? lis)
0)
(;; Recurring, first case: the first element is even, so square it
;; and add to the result of summing the square of the evens of the rest of the list
(even? (car lis))
(+ (expt (car lis) 2)
(sum-square-evens (cdr lis))))
(else
;; Recurring, when the first element is not even
;; the result is obtained by summing the square of the evens of the rest of the list
(sum-square-evens (cdr lis)))))
最后是用foldl-map-filter
编写的函数:
(define (sum-square-evens-2 lis)
(foldl + 0 (map (lambda(x) (expt x 2)) (filter even? lis))))
但是请注意, foldl
不是R5RS Scheme的原始功能,因此您应使用具有#lang racket
规范的DrRacket运行程序,或者定义它或加载定义了它的库。
这是第二个函数的含义:
filter
将谓词应用于列表的所有元素,a返回一个新列表,其中包含满足谓词的所有元素。 在这种情况下,谓词是even?
,这样的结果(filter even? lis)
是所有的偶数的列表lis
。 map
高阶函数,以产生结果将应用到其第二个参数(列表)的第一个参数(在这种情况下,将其参数平方的函数)的结果。 因此(map ...)
的结果是一个新列表,其中包含原始列表的所有偶数元素的平方。 (foldl + 0 (n1 n2 ...nk))
返回(...((0 + n1) + n2) + ... + nk)
,因为它反复将二进制函数+
应用于列表,使用0
作为其第一个(左)操作数。 (请注意,在这种情况下, foldl
和foldr
是等效的,第二个计算的和为(n1 + (n2 + ...(nk + 0)...))
) 这就是我要做的; 我将为您提供sum
和square
的定义:
(sum (map square (filter even? '(1 2 3 5 8 9 10))))
在启动Scheme解释器时会自动加载的库中收集诸如sum
和square
类的便利函数非常方便,因此您可以毫不延迟地编写这样的简单表达式。
您的sum_even
名称可能错误,因为它将每个元素平方并加在一起,因此square-sum
也许是一个更好的名称。
如果您希望对偶数放置的元素进行平方和求和,则只需使用已发布的两个过程:
(define (square-sum-even lst)
(square-sum (evens lst)))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.