方案,如何在列表中仅对负数进行平方,使列表的其余部分保持不变

时间:2012-10-31 00:40:29

标签: list scheme mit-scheme accumulate

我一直致力于积累电话,具体如下:

(define (accumulate op initial sequence)
  (if (null? sequence)
      initial
      (op (car sequence)
          (accumulate op initial (cdr sequence)))))

然而,当我试图通过过滤器选择它时,答案不起作用。到目前为止我所拥有的是:

(define (f2b items)
   (accumulate (lambda (x y)
     (cons (append 
        (map square (filter negative? (filter number? x))) x) y)) () items)
  )

我提供的输入是:

(f2a '(("sdas" 89) (-53 "sad")))

我得到的输出是:

 ((sdas 89) (2809 -53 sad))

我似乎无法让负数消失。

2 个答案:

答案 0 :(得分:2)

实际上,您描述的功能通常不是累加器的工作。相反,在列表中排除负数看起来像是地图之类的完美工作。

首先,让我们做:

(define (make-positive x)
    (if (and (number? x) (negative? x))
        (square x)
        x))

现在假设我们想要在名为lst的列表上操作。如果它只是一个平面列表,如'(1 "2" -5 -4 6),那么我们可以

(map make-positive lst)

由于我们需要对嵌套两层深度的列表进行操作,我们可以这样做:

(map (lambda (x)
        (map make-positive x))
     lst)

如果我们想对任意深度嵌套的列表进行操作,我们可以这样做:

(define (nested-map fn elm)
   (if (list? elm)
       (map (lambda (x) (nested-map fn x)) elm)
       (fn elm)))

(nested-map make-positive lst)

PS - 我们可以像这样定义map

(define (map fn lst)
   (if (empty? lst)
       '()
       (cons (fn (car lst))
             (map fn (cdr lst)))))

答案 1 :(得分:2)

使用过滤器和地图会容易得多。过滤器是预定义的,但它看起来像这样。

   (define (filter1 predicate sequence)
          (cond 
               ((null? sequence) null)
                ((predicate (car sequence))
                 (cons (car sequence)
                       (filter predicate (cdr sequence))))
                (else (filter predicate (cdr sequence)))))

map也是预定义的,它只是在列表上运行一个函数。

编写这个应该非常简单,但是如果您需要帮助,只需在过滤器中为谓词编写lamdba。