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

时间:2015-09-08 03:59:59

标签: list recursion scheme r5rs

(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和map方面编写第二个版本过滤即可。希望任何熟悉r5rs的人都可以帮助我!谢谢!

3 个答案:

答案 0 :(得分:2)

首先,您的功能是错误的,因为您没有测试列表的数量是否均匀。这应该是正确的定义:

;;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运行程序,或者您应该定义它或加载它所在的库。定义

以下是第二个功能的含义:

  1. filter将谓词应用于列表的所有元素,a返回包含满足谓词的所有元素的新列表。在这种情况下,谓词为even?,因此(filter even? lis)的结果是所有偶数lis的列表。
  2. 在此列表中应用map高阶函数,以生成应用于其第二个参数(列表)的函数第一个参数(在本例中为对齐其参数的函数)的结果。因此(map ...)的结果是一个新列表,其中包含原始列表中所有偶数元素的方块。
  3. 最后,(foldl + 0 (n1 n2 ...nk))返回(...((0 + n1) + n2) + ... + nk),因为它重复将二进制函数+应用于列表的元素,使用0作为其第一个(左)操作数。 (请注意,foldlfoldr在这种情况下是等价的,第二个计算总和为(n1 + (n2 + ...(nk + 0)...))

答案 1 :(得分:0)

这是我怎么做的;我将向您提供sumsquare的定义:

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

在启动Scheme解释器时自动加载的库中收集诸如sumsquare之类的便利函数非常方便,因此您可以毫不拖延地编写这样的简单表达式。

答案 2 :(得分:0)

您的/haha/bbb可能有一个错误的名称,因为它会对每个元素求平方并将它们加在一起,因此sum_even可能是一个更好的名称。

如果您希望将平均放置的元素平方并求和,则只需使用您发布的两个过程:

square-sum