2012-06-05 18 views

回答

12

您将返回一个新列表。如果你真的有兴趣在列表中的笛卡尔积,那么这应该足够:

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

如果你不希望使用串连,因为这不是一个尾递归操作,您可以使用下面的(这应该是更有效):

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 
1

我将问题分解成两个子问题:

  • 首先考虑功能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);; 
    
相关问题