OCaml:两组中每个值的排列? (如何从Java翻译)

时间:2009-10-02 02:28:32

标签: java ocaml permutation

我有两套,由Set.Make(t)返回。我想生成两者中值的所有可能组合。我怎么能这样做?

这可以生成一些对,但不是全部:

List.combine (IntSet.elements odp) (IntSet.elements ftw)

这将在Java中实现:

for (int i : ktr) {
     for (int m : mnx) {
       System.out.println(i + ", " + m);
     }
}

3 个答案:

答案 0 :(得分:6)

将@David Crawshaw的解决方案(尾递归)与@ newacct(完全通用)相结合:

let cartesian_product xs ys =
  List.fold_left (fun acc x -> 
    List.fold_left (fun acc y -> 
      (x,y) :: acc) 
      acc ys) 
    [] xs

let product = 
  cartesian_product (IntSet.elements odb) (IntSet.elements ftw)

这将颠倒自然顺序。可以通过将List.rev应用于结果来重新获得(List.rev也是尾递归的)。

答案 1 :(得分:5)

如果xsys是两个列表,那么他们的笛卡尔积(返回对列表)可以按如下方式计算:

List.concat (List.map (fun x -> List.map (fun y -> (x, y))
                                         ys)
                      xs)

在这种情况下,您的xsysIntSet.elements odpIntSet.elements ftw

答案 2 :(得分:3)

您正在寻找两套笛卡尔积。

在OCaml邮件列表中已经问过in a thread这个问题。这个答案由Brian Hurt提供:对于

module TypeSet = Set.Make(Type);;

创建,代表产品:

module TypeType = struct
    type t = Type.t * Type.t;;
    let compare (x1, x2) (y1, y2) =
        let r = Type.compare x1 y1 in
        if r == 0 then
            Type.compare x2 y2
        else
            r
    ;;
end;;

module TypeTypeSet = Set.Make(TypeType);;

然后用:

生成产品
let cartesian_product s1 s2 =
    let f x y t = TypeTypeSet.add (x, y) t in
    let g x t = TypeSet.fold (f x) s2 t in
    TypeSet.fold g s1 TypeTypeSet.empty
;;