使用 Foldr/Foldl 交替求和(球拍)

Alternating Sum Using Foldr/Foldl (Racket)

再次返回另一个球拍问题。总体上对高阶函数不熟悉,所以给我一些回旋余地。

目前正在尝试使用 foldr/foldl 函数而不是递归来查找交替和。

例如(altsum '(1 3 5 7)) 应该等于 1 - 3 + 5 - 7,总计为 -4。

我想过几种可能的方法来解决这个问题:

  1. 获取一个列表中要加的数字和另一个列表中要减去的数字并将它们折叠在一起。
  2. 以某种方式使用列表长度来确定是减去还是添加。
  3. 也许生成某种'(1 -1 1 -1) 掩码,分别相乘,然后折叠添加所有内容。

但是,当列表中的每个项目的每个操作都不相同时,我不知道从哪里开始 foldl/foldr,所以我无法实现我的任何想法。此外,每当我尝试在我的 foldl 的匿名 class 中添加 2 个以上的变量时,我也不知道之后哪些变量引用了匿名 class 中的哪些变量。

任何帮助或指点将不胜感激。

我们可以在这里利用两个高阶过程:foldr 用于处理列表,build-list 用于生成要执行的交替 操作 的列表。请注意,foldr 可以接受多个输入列表,在这种情况下,我们获取一个数字列表和一个操作列表,并按元素迭代它们,累积结果:

(define (altsum lst)
  (foldr (lambda (ele op acc) (op acc ele))
         0
         lst
         (build-list (length lst)
                     (lambda (i) (if (even? i) + -)))))

它按预期工作:

(altsum '(1 3 5 7))
=> -4

你的想法不错。您可以使用 range 制作一个数字 0 到长度为 1 的列表,并使用每个数字的奇数来确定 +-:

(define (alt-sum lst)
  (foldl (lambda (index e acc)
          (define op (if (even? index) + -)) 
          (op acc e))
        0
        (range (length lst))
        lst))

作为一种替代方法,可以使用 SRFI-1 List Library,其中 fold 允许不同长度的列表以及无限列表,与 circular-list 一起,您可以在 [=13] 之间切换=] 和 -,持续时间为 lst

(require srfi/1) ; For R6RS you import (srfi :1)

(define (alt-sum lst)
  (fold (lambda (op n result)
           (op result n))
         0
         (circular-list + -)
         lst))

(alt-sum '(1 3 5 7))
; ==> -4