如何将一个值乘以方案列表中的下一个值?

How to Multiply a value to the next value in a list in scheme?

有没有办法将列表中的每个值相乘, 然而,不是像这样得到另一个列表 (2 4 6), 你得到所有值的乘积。

(define (multi x y)
  (if (null? y)
     '()
     (* x (car y))))
(multi 2 '(1 2 3))
2 * 1 * 2 * 3
==> 6

这对某些人来说可能很简单,但我在这里有一个代码块,所以请不要在评论中无礼。谢谢。

使用,使用此系统将迭代输入而不构建新列表而仅更改累加器。

(fold-right * 1 '(2 3 4))
(fold-left * 1 '(2 3 4))

虽然fold是为此类操作提供的功能方案,但它并不能帮助您了解如何自己做。

让我们从一个合适的列表开始:

(1 . (2 . (3 . ())))

我们希望将其所有元素相乘:

{(1 . (2 . (3 . ())))} => 1 * 2 * 3

考虑列表的方式是:如果我可以对列表的其余部分进行头部操作,那么我可以对整个列表进行操作。

让我们重写乘法:

{(1 . (2 . (3 . ())))} => (1 * {(2 . (3 . ()))})
                       => (1 * (2 * {(3 . ())}))
                       => (1 * (2 * (3 * {()})))

我们可以将 null 变成 1,以便乘法有效:

{(1 . (2 . (3 . ())))} => (1 * (2 * (3 *  1 )))

折叠序列给我们:

(1 * (2 * 3))
(1 * 6)
6

因为你的函数不应该接受除列表之外的任何参数,所以这样写:

(define (multiply-list xs)

别忘了把 '() 变成 1:

  (if (null? xs)
      1

现在我们只需要处理神奇的递归部分。记住,如果我能用头做点什么...

      (* (car xs)

...相对于其余部分 - 必须通过乘以它来折叠...

         (multiply-list (cdr xs))

...那么你就完成了!

这假定它对 (multiply-list '())1 有效。

如果它需要变成其他任何东西(例如 '()0),那么您将不得不使递归部分更复杂一些。您仍然需要检查列表是否为 null 和 return 奇怪的值,但是您还必须确保在到达初始 non-empty 列表的末尾时不调用递归。

(define (multiply-list xs)
  (if (null? xs)
      0  ; or whatever weirdness is required to return if the initial list is empty
      (if (null? (cdr xs))  ; now we only want to recurse if there are more elements in the tail
          dont-recurse-here
          recurse-here)))
(define (mult x lst)
  (if (null? lst)
      x
      (mult (* x (car lst))(cdr lst))))