找到OCaml中所有三个列表中至少存在的一个元素

时间:2013-01-17 17:56:20

标签: algorithm functional-programming ocaml

  

我们有三个包含人名的列表。

     

所有三个列表都按字母顺序排序。

     

现在我们需要找到至少一个出现在所有三个列表中的名称。


我想的算法是这样的:

  

我从三个名单中得到三个头。

     

如果三个头不相等,那么我保持最大值   一个,从我刚刚放弃的列表中得到两个新头   头。

     

继续上述程序,直到找到如上所述的元素   一开始。

此算法是否正确?


问题在于我不确定如何使用ocaml来编写函数

2 个答案:

答案 0 :(得分:7)

这是一个OCaml函数,它使用你的算法完成两个排序列表的交集(这确实是解决这个问题的好方法)。

let rec intersect l1 l2 = match l1, l2 with
| [], _ | _, [] -> []
| h1 :: t1, h2 :: t2 ->
  if h1 < h2 then intersect t1 l2
  else if h1 = h2 then h1 :: (intersect t1 t2)
  else intersect l1 t2

答案 1 :(得分:3)

Thomash的算法将通过两次intersect调用并创建中间列表来完成工作,因此效率不高。

您的算法基本上是正确的。额外的一点是,有时你有两个头等于最大值,你应该只丢弃剩余的头。

以下是用OCaml编写的修订算法:

let rec intersect xs ys zs =
    match xs, ys, zs with
    | [], _, _ | _, [], _ | _, _, [] -> None
    | x::xs', y::ys', z::zs' -> 
       if x = y && y = z then Some x
       else 
           let m = max x (max y z) in
           if x = m && y = m then intersect xs ys zs'
           else if x = m && z = m then intersect xs ys' zs
           else if y = m && z = m then intersect xs' ys zs
           else if x = m then intersect xs ys' zs'
           else if y = m then intersect xs' ys zs'
           else intersect xs' ys' zs