0

我最近在课堂上参加的考试并没有做得太热。然而,由于其他人也对它进行了轰炸,我们的教授愿意通过向她证明我们知道 Scheme(不是很擅长......)来给我们一些“弥补”点。不过,她会问与考试内容不同的问题。所以我正在研究测试中的问题,以便更好地使用 Scheme,但我似乎无法让下面的问题起作用。

编写一个带有两个参数的 Scheme 函数 reduce:f,一个带有单个参数的函数,和 x,一个任意值。reduce 函数使用 x 中包含的每个嵌套列表递归调用 f,然后用调用 f 的结果替换原始嵌套列表。

例如,调用 (reduce (lambda(x) (cons 'list x)) '(3 7 9 zs (3 (78 2 3)))) 应该返回:

'(列表 3 7 9 zs (列表 3 (列表 78 2 3)))

此外,调用 (reduce (lambda (x) (cdr x)) '(3 7 9 zs (3 (78 2 3)))) 应该返回:

'(7 9 zs ((2 3))),其中第一个元素从每个嵌套列表中删除。

这是我想出的代码:

(define reduce
  (lambda (f x)
    (if (null? x)'()
    (let ((var (car x)))
    (cond
      ((cons? var) (cons (f var) (reduce f (cdr x))))
      ((symbol? var) (cons var (reduce f (cdr x))))
      ((number? var) (cons var (reduce f (cdr x)))))))))

如果我输入示例输入,这些是我的结果:

(减少 (lambda(x) (cons 'list x)) '(3 7 9 zs (3 (78 2 3))))

(list 3 7 9 'z's (list 'list 3 (list 78 2 3)))

有一个额外的'清单来自谁知道在哪里

;

(减少 (lambda(x) (cdr x)) '(3 7 9 zs (3 (78 2 3))))

(list 3 7 9 'z's (list (list 78 2 3)))

它只删除了第二个嵌套循环中的 3。它应该删除第一个中的 3、中间的 3 和第三个中的 78。它也不应该有“列表”这个词

;

我假设问题出在一行((cons?var),但我似乎无法弄清楚如何解决它。

我们对Scheme语言没有深入,所以我们还没有学到很多特殊的方法;这主要是递归。

任何帮助将非常感激。

谢谢。

4

1 回答 1

1

这是我的实现:

(define (reduce f x)
  (define (inner x)
    (if (list? x)
        (f (map inner x))
        x))
  (inner x))

例子:

> (reduce (lambda (x) `(list ,@x)) '(3 7 9 z s (3 (78 2 3))))
(list 3 7 9 z s (list 3 (list 78 2 3)))
> (reduce cdr '(3 7 9 z s (3 (78 2 3))))
(7 9 z s ((2 3)))

这是一个不map直接使用的版本,但基本上是重新实现map(尽管使用了硬编码的转换器):

(define (reduce f x)
  (define (transform lst)
    (if (null? lst)
        '()
        (cons (process (car lst)) (transform (cdr lst)))))
  (define (process x)
    (if (list? x)
        (f (transform x))
        x))
  (process x))
于 2013-11-13T21:28:17.743 回答