我有两个列表:如何在OCaml中使用两个列表的产品?
let a = ["a";"b"];
let b = ["c";"d"];
我想要的输出列表C如:
c = ["a";"c";"a";"d";"b";"c";"b";"d"];
怎么办呢OCaml中的列表是不可改变的?我对它很陌生。
我有两个列表:如何在OCaml中使用两个列表的产品?
let a = ["a";"b"];
let b = ["c";"d"];
我想要的输出列表C如:
c = ["a";"c";"a";"d";"b";"c";"b";"d"];
怎么办呢OCaml中的列表是不可改变的?我对它很陌生。
您将返回一个新列表。如果你真的有兴趣在列表中的笛卡尔积,那么这应该足够:
let cartesian l l' =
List.concat (List.map (fun e -> List.map (fun e' -> (e,e')) l') l)
# cartesian ["a";"b"] ["c";"d"];;
- : (string * string) list = [("a", "c"); ("a", "d"); ("b", "c"); ("b", "d")]
如果你需要奇怪的扁平结构,而不是,你可以使用一个额外的连接列表。
let flat_cartesian l l' =
List.concat (List.concat (
List.map (fun e -> List.map (fun e' -> [e;e']) l') l))
如果你不希望使用串连,因为这不是一个尾递归操作,您可以使用下面的(这应该是更有效):
let product l1 l2 =
List.rev (
List.fold_left
(fun x a ->
List.fold_left
(fun y b ->
b::a::y
)
x
l2
)
[]
l1
)
;;
对于笛卡尔积,只是改变
b::a::y
到
(a,b)::y
我将问题分解成两个子问题:
首先考虑功能appendeach与取一个值和一个列表,返回列表中添加该值盈每个项目的结果
let rec appendeach x lst = match lst with [] -> []
| hd::tl -> x::hd::(appendeach x tl);;
再考虑功能产品,需要两个列表,并呼吁appendeach在第一列表中的每个项目和整个第二列表
let rec product lst1 lst2 = match lst1 with [] -> [] |
hd::tl -> (appendeach hd lst2)@(product tl lst2);;