简体   繁体   English

R5RS方案代码找到列表中偶数元素的和(递归和高阶抽象)?

[英]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))

Here is my attempt to find the sum of the squares of the even elements in the list. 这是我尝试查找列表中偶数元素的平方和。 However, I am really new to r5rs, is that possible I can write these scheme into only one procedure? 但是,我对r5rs真的很陌生, 是否可以将这些方案仅编写到一个过程中? Also, I was asked to write a second version in terms of map, foldr, and filter . 另外, 还要求我编写有关map,foldr和filter的第二个版本 Hope anyone familiar with r5rs can help me out! 希望任何熟悉r5rs的人都能帮助我! Thanks! 谢谢!

First of all, your function is wrong since you do not test the numbers of the list for evenness. 首先,您的功能是错误的,因为您没有测试列表编号的均匀性。 This should be the correct definition: 这应该是正确的定义:

;;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)))))

Then, to answer to your first question, this is a solution with a single recursive function: 然后,为了回答您的第一个问题,这是一个具有单个递归函数的解决方案:

;;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)))))

Finally here is the function written with foldl-map-filter : 最后是用foldl-map-filter编写的函数:

(define (sum-square-evens-2 lis)
  (foldl + 0 (map (lambda(x) (expt x 2)) (filter even? lis))))

but note that foldl is not a primitive function of R5RS Scheme, so you should run your program with DrRacket with the #lang racket specification, or you should define it or load a library in which it is defined. 但是请注意, foldl不是R5RS Scheme的原始功能,因此您应使用具有#lang racket规范的DrRacket运行程序,或者定义它或加载定义了它的库。

Here is the meaning of the second function: 这是第二个函数的含义:

  1. filter applies a predicate to all the elements of a list, a returns a new list containing all the elements that satisfy the predicate. filter将谓词应用于列表的所有元素,a返回一个新列表,其中包含满足谓词的所有元素。 In this case the predicate is even? 在这种情况下,谓词是even? , so the result of (filter even? lis) is the list of all the even numbers of lis . ,这样的结果(filter even? lis)是所有的偶数的列表lis
  2. To this list the map high order function is applied, to produce as result the results of the function first argument (in this case a function that squares its argument) applied to its second argument (a list). 在此列表上应用了map高阶函数,以产生结果将应用到其第二个参数(列表)的第一个参数(在这种情况下,将其参数平方的函数)的结果。 So the result of (map ...) is a new list containing the squares of all the even elements of the original list. 因此(map ...)的结果是一个新列表,其中包含原始列表的所有偶数元素的平方。
  3. Finally, (foldl + 0 (n1 n2 ...nk)) returns (...((0 + n1) + n2) + ... + nk) , since it repeatedly applies the binary function + to the elements of the list, using 0 as its first (left) operand. 最后, (foldl + 0 (n1 n2 ...nk))返回(...((0 + n1) + n2) + ... + nk) ,因为它反复将二进制函数+应用于列表,使用0作为其第一个(左)操作数。 (Note that foldl and foldr are in this case equivalent, the second one calculating the sum as (n1 + (n2 + ...(nk + 0)...)) ) (请注意,在这种情况下, foldlfoldr是等效的,第二个计算的和为(n1 + (n2 + ...(nk + 0)...))

Here's how I would do it; 这就是我要做的; I'll leave to you the definitions of sum and square : 我将为您提供sumsquare的定义:

(sum (map square (filter even? '(1 2 3 5 8 9 10))))

It's handy to collect convenience functions like sum and square in a library that is loaded automatically when you start your Scheme interpreter, so you can write simple expressions like this without delay. 在启动Scheme解释器时会自动加载的库中收集诸如sumsquare类的便利函数非常方便,因此您可以毫不延迟地编写这样的简单表达式。

Your sum_even has perhaps a wrong name as it will square every element and sum it together, thus square-sum is perhaps a better name. 您的sum_even名称可能错误,因为它将每个元素平方并加在一起,因此square-sum也许是一个更好的名称。

If you wanted the even placed elements to be squared and summed you just use the two procedures you have posted: 如果您希望对偶数放置的元素进行平方和求和,则只需使用已发布的两个过程:

(define (square-sum-even lst)
  (square-sum (evens lst)))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM