0

晚上!

我需要在 Scheme 中编写一个reduce函数,它就像Python中的内置reduce函数一样工作。在 Scheme 中编写 reduce 函数很容易:

(define (reduce fn lis identity)
  (if (null? lis)
    identity
    (fn (car lis)
        (reduce fn (cdr lis) identity))))

但是,此代码与 Python reduce不同,后者仅接受两个参数(函数和要归约的项目列表)。

谁能我写一个以这种方式工作的 Scheme 函数?

(>(reduce * '(2 4 5 5)) => 200,是我们教授的例子。)

非常感谢,伙计们。你太有帮助了<3

ETA:非常感谢 Levien 先生和 Jester-Young 先生。您提供了完美的信息量来帮助我自己解决问题。*拥抱

4

3 回答 3

5

这很容易。累加器用列表的第一个元素初始化:

(define (py-reduce f ls) (fold f (car ls) (cdr ls)))

(py-reduce * '(2 4 5 5)) => 200

随意使用另一个 reduce 函数,而不是从 srfi-1 折叠(如 reduce、fold-right ...)或使用你自己的。您的列表至少需要一个元素。

于 2011-02-24T09:32:55.670 回答
2

拥有身份允许您的函数使用大小为零或更大的列表 - 当它是一个空列表时,您将获得身份。如果没有标识,该函数将仅适用于一个或多个元素的列表。一些函数自然有一个标识(加法为零,乘法等)。其他人则没有——min尤其max是在大整数上。

你应该能够弄清楚其余的:)

于 2011-02-24T04:21:00.980 回答
0

下面是一个尾递归版本。你的教授不太可能喜欢它(因为它没有展示递归;-)),但至少它会给你一些想法如何去做。

(define (reduce func lst)
  (let loop ((val (car lst))
             (lst (cdr lst)))
    (if (null? lst) val
        (loop (func val (car lst)) (cdr lst)))))

identity正如 Raph Levien 的出色回答所暗示的那样,如果传入列表为空(这就是参数的用途),此版本将不起作用。在这种情况下,你会得到一个错误(因为你不能carcdr一个空列表)。

于 2011-02-24T04:34:36.573 回答