2012-06-05 18 views
5

私は2つのリストがあります:リストは不変であるとして、OCamlではそれを行う方法をOCamlで2つのリストの製品を取る方法は?

c = ["a";"c";"a";"d";"b";"c";"b";"d"]; 

let a = ["a";"b"]; 
let b = ["c";"d"]; 

を私のような出力リストcをしたいですか?私はそれが初めてです。

答えて

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

デカルト積については、ただ

(a,b)::y 

b::a::y 

を変更私は2つのサブ問題に問題を破る210

1

  • まずで機能appendeachを考えるには、値とリストを受け取り、リスト

    に各項目のインフロント、その値を加算した結果を返します。
    let rec appendeach x lst = match lst with [] -> [] 
                 | hd::tl -> x::hd::(appendeach x tl);; 
    
  • は次に、2つのリストを受け取り、最初のリストの各項目についてappendeachを呼び出し、全体の第二のリスト

    let rec product lst1 lst2 = match lst1 with [] -> [] | 
                 hd::tl -> (appendeach hd lst2)@(product tl lst2);; 
    
  • と機能の製品を検討します
関連する問題