Scheme:使用不带递归的抽象列表函数

时间:2012-03-20 20:55:14

标签: scheme

如何使用抽象列表函数(foldrfoldlmapfilter)编写函数,而不使用消耗数字列表的递归{{1并生成交替的和(list a1 a2 a3 ...)

3 个答案:

答案 0 :(得分:8)

这是一个提示:

a1 - a2 + a3 - a4 ... aN

相同
a1 - (a2 - (a3 - (a4 - ... (aN - 0) ...)))

现在如何解决它是否明显?

答案 1 :(得分:1)

这是一个可能的解决方案:

(define (sum-abstract-list-functions lst)
  (car
   (foldl
    (lambda (e acc)
      (cons (+ (car acc) (* e (cdr acc)))
            (- (cdr acc))))
    '(0 . 1)
    lst)))

我只使用foldlconscarcdr。诀窍?累加两个值:实际总和(在累加器的car部分中)和当前符号(累加器的cdr部分中的+/- 1)。累加器初始化为0表示总和,+1表示符号,最后我返回总和,即累加器的car部分。像这样使用它:

(sum-abstract-list-functions (list 1 2 3 4 5))
> 3

编辑:

正如已经指出的,这个解决方案是最简单的:

(define (sum-abstract-list-functions lst)
  (foldr - 0 lst))

答案 2 :(得分:1)

这是家庭作业吗?好吧,我们可以将这个问题分成两个子问题:

  • 列出(a1 a2 a3 a4 ... a2n-1 a2n)列表并交替否定其中的元素,以生成(a1 (- a2) a3 (- a4) ... a2n-1 (- a2n))
  • 对结果列表的元素求和。

第二部分是微不足道的:

(define (sum xs)
  (foldl + 0 xs))

第一个是更难的,但它并不太难。您需要转换列表,同时保持一个布尔状态,指示您是在检查偶数元素还是奇数元素,并相应地否定。我可以看到三种方法:

  • 突变方式:将状态放入传递给map的闭包中。闭包然后从一次调用到下一次调用修改其环境。
  • 将状态保持在折叠结果中:折叠结果是包含“实际”结果和状态作为元素的对。
  • 使用不同类型的抽象列表函数。

这是第三种方法的一个例子(如果这是用于家庭作业,我打赌你的老师可能不相信你想出来了):

(define (contextual-foldr compute-next
                          compute-init
                          advance-context
                          left-context
                          xs)
  (if (null? xs)
      (compute-rightmost-result left-context)
      (compute-next left-context
                    (car xs)
                    (contextual-foldr compute-next
                                      compute-init
                                      advance-context
                                      (advance-context (car xs) left-context)
                                      (cdr xs)))))

(define (contextual-map contextual-fn advance-context left-context xs)
  (contextual-foldr (lambda (left elem rest)
                      (cons (fn left elem) rest))
                    '()
                    advance-context
                    left-context
                    xs))

(define (alternate-negations xs)
  (contextual-map (lambda (negate? elem)
                    (if negate?
                        (- elem)
                        elem))
                  not
                  #f
                  xs))