返回矩形范围内的元组列表

时间:2019-01-12 22:16:03

标签: ocaml fold

作为OCaml的初学者,我正在尝试编写一个带有两个int参数(a和b)的函数,并且应该返回一个包含所有元组(i,j)的列表,其中i在0和a之间,并且j在0到b之间,顺序无关紧要。 该函数应如下所示:myfunc:int-> int->(int * int)列表 结果必须类似于[(0,1);(0,2)] ...

我已经编写了一个函数,该函数接受两个int参数并返回这两个参数之间的列表。例如,1和5给我以下列表:[1; 2; 3; 4; 5]。 这就是我所做的:

let rec btwn = fun a b -> if a>b then []
                       else if a = b then [a]
                       else a :: btwn (a+1) b ;;

我的想法是重用此功能,并创建两个列表:一个范围为0的列表; a和彼此的范围为0; b,然后使用这两个列表创建所有元组。 我听说过List.fold_left / right,List.map,但我无法正常工作... 你有什么想法 ?谢谢!

2 个答案:

答案 0 :(得分:0)

以下代码有效:

let createTuples (i:int) (j: int)=
      let rec helper1 acc i j=
        match i with 
        |0 -> (0,j)::acc
        |q -> helper1 ((q,j)::acc) (q-1) j
      in let rec helper2 acc p o=
           match o with
           |0 -> (helper1 [] p 0)@acc
           |q -> helper2 ((helper1 [] p q)@acc) p (o-1)
      in helper2 [] i j

代码通过迭代两个给定的索引0

答案 1 :(得分:0)

如果您想重用btwn,则基本上想实现此功能::

fun a b -> 
  let la = btwn 0 a
  and lb = btwn 0 b
  in cartesian_product la lb;;

现在,您只需要实现cartesian_product,它基本上是两个嵌套循环:从a到元素la的外部循环,对于每个a,您对b中的所有元素lb进行了迭代,以构建列表[(ai,b0),...,(ai,bj)]。然后,您必须串联所有列表(一个用于a0,然后是a1等)。

在伪代码中,应为:

R = []
loop for a in la:
  R := append(R, [(a,b) for b in lb])

但是,您可以将结果列表穿入参数和中间返回值中,而不必进行串联,以确保始终只在前面添加元素,这需要花费固定时间:

let cross_product la lb =
  let rec outer sofar la =
    match la with
    | [] -> sofar
    | a::la -> 
       let rec inner sofar lb =
         match lb with
         | [] -> sofar
         | b::lb -> (inner ((a,b)::sofar) lb)
       in outer (inner sofar lb) la
  in outer [] la;;

如果您不介意具有局部可变状态,则一种更简单的方法是:

open List;;
let cross_product la lb =
  let stack = ref []
  in iter (fun a -> iter (fun b -> stack := (a,b)::!stack) lb) la;
     !stack;;