4

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

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

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


我想的算法是这样的:

我从三个列表中得到三个正面。

如果三个头彼此不相等,那么我保留最大的一个并从我刚刚丢弃头的列表中获得两个新头。

继续上面的过程,直到我找到开头描述的这样一个元素。

这个算法正确吗?


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

4

2 回答 2

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
于 2013-01-17T18:08:09.307 回答
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
于 2013-01-17T18:45:47.453 回答