2017-03-07 50 views
0

関数名:intersection:2つのリストを取り、両方に表示されるすべての要素のリストを返します。Ocaml:再帰:intersection

ie:[1; 2; 2; 3; 4; 4; 3] [2; 3]→[2; 2; 3; 3]

let rec intersection (l1: int list) (l2: int list) : int list = 
    begin match l1, l2 with 
     | hd :: tl, hd2 :: tl2 -> if hd = hd2 then hd :: intersection tl l2 
              else intersection tl l2 
     | _ -> [] 
    end 

このコードに問題がありますが、修正方法がわかりません。コードは実行され、[2; 2] l2の最初の要素である2と比較し続けますが、l1もtl2と比較したいのですが、誰にでも提案がありますか?

Should I add another match [], [] -> to clarify base case at the beginning? 
+2

*あなたはどのように書きますか?あなたはどんな問題に直面していますか?あなたの試みを私たちに示すか、あなたのアプローチについて教えてください。 StackOverflowはあなたの宿題に役立つことができますが、私たちはあなたのためにそれを解決しません。 – Bergi

+0

このコードを実装する効率的な方法はありますか? 他のすべて:2番目の要素ごとに ie:[1; 2; 3; 4; 5]→[1; 3; 5] let every_other(l:intリスト)を書きましょう:int list = begin match lを と開始します。 [] - > [] | hd :: tl-> hd :: every_other tl end – anonymoususer

+0

またはこれ? let all_even(l:int list):bool =マッチlを開始する| [] - > true | hd :: tl - >(hd mod 2 = 0)&& all_even tl end – anonymoususer

答えて

0

どのように他のリストの最初の要素を参照していますか?

matchステートメントを使用します。

let rec intersection (l1: int list) (l2: int list) : int list = 
    begin match l2 with 
     | []   -> [] 
     | hd2 :: tl2 -> begin match l1 with 
         | []   -> … 
         | hd1 :: tl1 -> … 
         end 
    end 

ます。また、この場合には不要ですbegin/end括弧を省略し、そしてすぐにタプル時に照合することによって、これを簡略化することができます。

let rec intersection (l1: int list) (l2: int list) : int list = match l1, l2 with 
    | [],  _  -> [] 
    | hd1::tl1, []  -> … 
    | hd1::tl1, hd2::tl2 -> … 

(免責事項:私は、同じ関数の2つの最初の要素を見ることが有用かどうかという疑問を無視しましたr intersectionを実装しています)

+0

あなたはl1、l2を| []、[] - > | hd1 :: tl1、hd2 :: tl2、それとももっと効率が悪いですか? – anonymoususer

+0

または "contains"のようなヘルパー関数を記述し、containsがtrueならhd1 :: intersection tl – anonymoususer

+0

はい、そうすることができますが、空/空でないリストの4つのケースすべてをカバーすることを忘れないでください – Bergi

関連する問題