计划 - 迭代两个列表

时间:2017-04-19 20:59:26

标签: functional-programming scheme

大家好,我是学习计划的新手,经常遇到在命令式语言和函数式语言之间做出相似之处的问题。

例如,如果我有两个数组。

A = [1 2 3]
B = [4 5 6]

如果我想创建一个新元素,其中元素A乘以B中的每个元素,我可以简单地执行类似(伪代码)的操作:

for(int i = 0; i < A.length; i++)
    for(int j = 0; j < B.length, j++)
        arr.push(A[i]*B[j])

哪会回馈:

arr = [4 5 6 8 10 12 12 15 18]

用函数式语言解决这个问题会有什么方法?

2 个答案:

答案 0 :(得分:4)

在Scheme中,最常见的数据结构是链表。除非你必须按索引访问元素,否则总是首选使用列表,因为有无数的内置过程来处理列表,这使得很容易实现大多数算法而不使用索引。请记住,为了通过索引进行有效访问,使用向量将是一个更好的主意。

话虽如此,根据您使用的Scheme方言,解决方案可以像这样简单(在Racket中,请参阅documentation):

(define a '(1 2 3))
(define b '(4 5 6))

(for*/list ([x a] [y b])
  (* x y))

=> '(4 5 6 8 10 12 12 15 18)

或者,仅使用标准Scheme:

(apply append
       (map (lambda (x)
              (map (lambda (y) (* x y))
                   b))
            a))

答案 1 :(得分:0)

在Scheme和Racket数组中(数组:由自然数索引的数据结构)使用向量表示。

(define as  (vector 1 2 3))
(define bs  (vector 4 5 6))

要制作循环内循环,我们将使用for*的变体。 普通for*的工作原理如下:

(for* ([a as] [b bs])
   (displayln (* a b))))

此处a遍历向量as的元素,b遍历bs中的元素。由于使用for*,因此b循环在a循环内运行。 如果使用for而不是并行运行循环(尝试)。

既然我们要收集元素,我们可以使用for*/vector将生成的元素存储在向量中:

(for*/vector ([a as] [b bs])
  (* a b)))

出于效率原因,可以写:

(for*/vector ([a (in-vector as)] [b (in-vector bs)])
  (* a b)))

这将生成更有效的代码。

然而

(for*/vector ([a as] [b bs])
  (* a b)))
如果asbs是列表,

也会有效。