2

我有一个简单的列表,其中的整数总是偶数,例如

(42 38 15 5)

我想计算其对差异的总和,即

(+ (- 42 38) (+ 15 5)) --> 14

它可以是 2、4 或更多元素,但它始终是偶数。我认为有一种方法可以使用 reduce 来解决这个问题,但我看不出有一种方法可以让配对正确。

有没有一种简单的方法可以做到这一点,或者更改列表结构更容易?例如像

((42 38) (15 5))
4

2 回答 2

4

您可以loop为此使用:

(loop :for (a b) :on list :by #'cddr
      :sum (- a b))

for-on构造越过列表的尾部,可以对其for进行解构,by提供步进功能(默认#'cdr)。

如果您绝对想使用高阶函数,则需要先分区(正如您已经推测的那样)或找到步进机制。

分区可以再次通过loop或通过 cons-fiddling 来完成。之后,您可以减少:

(reduce (lambda (sum pair)
          (+ sum (apply #'- pair)))
        (partition 2 list)
        :initial-value 0)

或者,您可以将其视为交替加减数字:

(reduce #'+
        (mapcar #'funcall
                (circular-list #'+ #'-)
                list))

Circular-list来自alexandria。)

于 2018-12-14T11:01:24.990 回答
2

您还可以使用较短的循环:

(loop 
   while list 
   sum (- (pop list)
          (pop list)))
于 2018-12-14T16:29:31.600 回答