大家好,我是学习计划的新手,经常遇到在命令式语言和函数式语言之间做出相似之处的问题。
例如,如果我有两个数组。
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]
用函数式语言解决这个问题会有什么方法?
答案 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)))
如果as
和bs
是列表,也会有效。