2017-03-07 90 views
0

函數名稱:交集:取2個列表並返回出現在所有元素中的列表Ocaml:遞歸:交集

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中的第一個元素相比,但是我想讓l1也與tl2比較,有沒有人有任何建議?

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

*你會怎樣寫它?你面臨什麼問題?請向我們展示您的嘗試或告訴我們您的方法。 StackOverflow可以幫助你做家庭作業,但我們不會爲你解決它。 – Bergi

+0

有沒有更有效的方法來實現這個代碼? 每隔一個:每個第二個元素 ie:[1; 2; 3; 4; 5] - > [1; 3; 5] let rec every_other(l:int list):int list = begin match l with | [] - > [] | hd :: tl - > hd :: every_other tl end – anonymoususer

+0

或者這個? let rec all_even(l:int list):bool =開始匹配l with | [] - > 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 -> … 

(免責聲明:我忽略了在相同函數中查看兩個第一個元素是否有用的問題r完全執行intersection

+0

您可以開始與l1,l2匹配| [],[] - > | hd1 :: tl1,hd2 :: tl2還是更低效? – anonymoususer

+0

或者我可以寫一個幫助函數,如「contains」,然後如果contains爲true,那麼hd1 :: intersection tl – anonymoususer

+0

是的,你可以這樣做,但不要忘記覆蓋空/非空列表的所有四種情況 – Bergi