Ocaml 笛卡尔积(复杂性改进)

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)) `

我想写一个函数,给出两个序列的笛卡尔积,这就是我所做的,但我认为它的复杂性可能会低一些,我想使用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 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)]。这是预期的结果吗?是的,这里我使用的是序列而不是列表,但这是相同的操作