【问题标题】:Alternating Sum Using Foldr/Foldl (Racket)使用 Foldr/Foldl 交替求和(球拍)
【发布时间】:2018-06-15 19:18:02
【问题描述】:

再次返回另一个球拍问题。一般是高阶函数的新手,所以给我一些余地。

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

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

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

  1. 在一个列表中获取要相加的数字,在另一个列表中获取要减去的数字,然后将它们折叠在一起。
  2. 不知何故使用列表长度来确定是减还是加。
  3. 可能会生成某种 '(1 -1 1 -1) 掩码,分别相乘,然后折叠相加。

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

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

【问题讨论】:

    标签: scheme racket fold alternating


    【解决方案1】:

    我们可以在这里利用两个高阶过程: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
    

    【讨论】:

      【解决方案2】:

      你的想法没问题。您可以使用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一起,您可以让它在+-之间切换,持续时间为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
      

      【讨论】:

      • 我不敢相信我忘记了交替求和的偶数/奇数。再次感谢您的帮助。我也很喜欢 SRFI-1 列表库的循环列表功能,所以感谢您提及它。
      猜你喜欢
      • 1970-01-01
      • 2015-01-08
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 1970-01-01
      • 2016-09-04
      • 2011-08-28
      • 2010-09-27
      相关资源
      最近更新 更多