我们有三个包含人名的列表。
所有三个列表都按字母顺序排序。
现在我们需要找到至少一个出现在所有三个列表中的名称。
我想的算法是这样的:
我从三个名单中得到三个头。
如果三个头不相等,那么我保持最大值 一个,从我刚刚放弃的列表中得到两个新头 头。
继续上述程序,直到找到如上所述的元素 一开始。
此算法是否正确?
问题在于我不确定如何使用ocaml来编写函数。
答案 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