首页 > 解决方案 > 如何将指数应用于球拍中的内置列表

问题描述

在此处输入图像描述所以我知道如何使用 build-list 在球拍中建立一个列表

例如:

(build-list 2 add1) => (list 1 2)

但是,如果我想将指数应用于列表,它以某个数字结尾,我将如何去做。

例如:指数 3,它将从 0 开始并在 3 结束,将其应用于构建列表中的 1 和 2。

1^0 * 1^1 * 1^2 * 1^3 
2^0 * 2^1 * 2^2 * 2^3 

大概是我所拥有的。

(define (list-of-numbers m n)
(apply * (build-list (get m) (lambda (n) (expt n n)))))

  (define (get m)
    (build-list m add1))

输出应该是:

(list-of-numbers 2 3) ⇒ (list 1 64)

1 × 1 × 1 × 1 = 1 
1 × 2 × 4 × 8 = 64

标签: schemeracket

解决方案


使用的解决方案build-list可以从构建m元素列表开始:

(build-list m add1)

在这里,(build-list 2 add1)-->(1 2)

接下来,可以再次使用map列表build-list来构造列表列表。我们将需要一个应用到列表的过程,例如(1 2),它将从每个元素构造一个列表。请注意,每个元素都应转换为n+1元素列表(在list-of-numbers 2 3我们有的情况下n == 3):

(lambda (x) (build-list (add1 n) some-procedure))

当此过程应用于来自 的元素时(1 2),我们应该得到一个类似(1 1 1 1), 或的列表(1 2 4 8)。为此,some-procedure将调用范围内的一个数字[0, n]。需要some-procedure做的是从第一个列表(x在上面的lambda表达式中)中取出它的数字,并从第二个列表(范围内的数字)中将它提升到它的数字的幂[0, n]。所以,现在可以写成some-procedure

(lambda (y) (expt x y))

这里,x取自第一个lambda表达式,y取自[0, n]提供的范围build-list。现在我们需要在我们构建的第一个列表上使用map这个复合lambda表达式:

(map (lambda (x) (build-list (add1 n) (lambda (y) (expt x y))))
     (build-list m add1))

如果我们分别用 2 和 3 的输入来测试上述映射的结果mn,我们会得到:

'((1 1 1 1) (1 2 4 8))

剩下的就是apply乘以这里的子列表;同样,我们可以在每个子列表上使用map一个lambda表达式,apply为我们留下一个结果列表:

(define (list-of-numbers m n)
  (map (lambda (s) (apply * s))
       (map (lambda (x) (build-list (add1 n) (lambda (y) (expt x y))))
            (build-list m add1))))

这是一些示例输出:

scratch.rkt> (list-of-numbers 2 3)
'(1 64)
scratch.rkt> (list-of-numbers 3 3)
'(1 64 729)
scratch.rkt> (list-of-numbers 3 2)
'(1 8 27)

有什么可以代替应用的吗?

apply可以map再次使用,而不是使用,使用与乘法一起lambda应用于子列表的表达式:foldl

(define (list-of-numbers-2 m n)
  (map (lambda (x) (foldl * 1 x))
       (map (lambda (x) (build-list (add1 n) (lambda (y) (expt x y))))
            (build-list m add1))))

工作方式与以前相同:

scratch.rkt> (list-of-numbers-2 2 3)
'(1 64)
scratch.rkt> (list-of-numbers-2 3 3)
'(1 64 729)
scratch.rkt> (list-of-numbers-2 3 2)
'(1 8 27)

推荐阅读