Ocaml 笛卡尔积(复杂性改进)
我想写一个函数,给出两个序列的笛卡尔积,这就是我所做的,但我认为它的复杂性可能会低一些,我想使用map浏览第一个序列s1和第二个序列n次,然后附加所有结果:Ocaml 笛卡尔积(复杂性改进),ocaml,Ocaml,我想写一个函数,给出两个序列的笛卡尔积,这就是我所做的,但我认为它的复杂性可能会低一些,我想使用map浏览第一个序列s1和第二个序列n次,然后附加所有结果: `let cartesian_product a b = let na = length a in let nb = length b in init (na * nb) (fun j -> let i = j / nb in at a i, at b (j - i*nb)) `
`let cartesian_product a b =
let na = length a in
let nb = length b in
init
(na * nb)
(fun j -> let i = j / nb in
at a i, at b (j - i*nb))
`
我当时就是这么做的:
`let rec cartesian_product a b =
let rec aux x b () = match b () with
| Nil -> Nil
| Cons(e, b) -> Cons ((x, e), aux x b)
in
match a () with
| Nil -> nil
| Cons (x, a) -> append (aux x b) (cartesian_product a b)`
但是我没有使用map(有更好的方法吗?您的
aux
函数本质上是map
的一个特例,因此您可以编写:
let rec cartesian_product a b = match a () with
| Nil -> Nil
| Cons (x, a) -> append (map (fun e -> (x, e)) b) (cartesian_product a b)
根据经验,当您觉得需要编写名为
aux
的函数时,请后退一步,考虑是否可以使用map
或fold
。事实上,您可以通过使用折叠来改进我的代码,而不是自己解构序列。下面是一个具有列表结构的算法示例:
let cartesian_product a b =
let open List in
let mk_tuple l n = map (fun x -> (n,x)) l in
a |> map (mk_tuple b) |> fold_left append []
这将为您提供:
cartesian_product [0;1] [2;3];;
- : (int * int) list = [(0, 2); (0, 3); (1, 2); (1, 3)]
举个例子:笛卡尔[0;1][2;3]将产生[(0,2);(0,3);(1,2);(1;3)]。这是预期的结果吗?是的,这里我使用的是序列而不是列表,但这是相同的操作