2017-03-07 91 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