我将发布到目前为止的自己的实现(仅联合操作),我正在使用一种函数式语言,所以请注意..可能会有些混淆:
let rec calc c l1 l2 =
match c,l1,l2 with
None, (f1,t1) :: y1, ((f2,t2) :: y2 as n2) when f1 < f2 -> calc (Some (f1,t1)) y1 n2
| None, n1, (f2,t2) :: y2 -> calc (Some (f2,t2)) n1 y2
| None, _, _ -> []
| (Some (fc,tc) as cur), (f1,t1) :: y1, ((f2,t2) :: y2 as n2) when t1 <= fc -> calc cur y1 n2
| (Some (fc,tc) as cur), ((f1,t1) :: y1 as n1), (f2,t2) :: y2 when t2 <= fc -> calc cur n1 y2
| Some (fc,tc), (f1,t1) :: y1, ((f2,t2) :: y2 as n2) when f1 <= tc && t1 > fc -> calc (Some (fc,t1)) y1 n2
| Some (fc,tc), ((f1,t1) :: y1 as n1), (f2,t2) :: y2 when f2 <= tc && t2 > fc -> calc (Some (fc,t2)) n1 y2
| Some (fc,tc), (f1,t1) :: y1, ((f2,t2) :: y2 as n2) when f1 < f2 -> [fc,tc] @ calc (Some (f1,t1)) y1 n2
| Some (fc,tc), (t :: e as n1), (f2,t2) :: y2 -> [fc,tc] @ calc (Some (f2,t2)) n1 y2
| Some (fc,tc), [], (f,t) :: tr when f <= tc && t > tc -> calc (Some (fc,t)) [] tr
| Some (fc,tc), [], (f,t) :: tr when f <= tc && t <= tc -> calc (Some (fc,tc)) [] tr
| Some (fc,tc), [], x -> [fc,tc] @ x
| Some (fc,tc), (f,t) :: tr, [] when f <= tc && t > tc -> calc (Some (fc,t)) tr []
| Some (fc,tc), (f,t) :: tr, [] when f <= tc && t <= tc -> calc (Some (fc,tc)) tr []
| Some (fc,tc), x, [] -> [fc,tc] @ x
它使用 c 参数来存储当前间隔(在其中合并重叠范围),而 l1 和 l2 是两个 int * int列表。
语法很简单,每行表示一个具有 c , l1 和 l2 以精确方式指定的单个用例。 让我给你一些例子:
(Some (fc,tc) as cur), (f1,t1) :: y1, ((f2,t2) :: y2 as n2) when t1 <= fc -> calc cur y1 n2
我有一个当前范围fc,tc
,两个列表至少包含一个元素(这就是为什么有(f1,t1)::y1
),所以如果t1 <= fc
,那么第一个列表的范围在当前范围之前结束,可以被丢弃,因此它会递归地调用自身,使用相同的cur
范围,y1
其中第一个被丢弃,n2
是作为参数接收的同一列表的别名。
对于每种情况都类似,当我发现没有下一个范围与cur
重叠时,我将cur
作为最终答案的一个元素返回,并从空白开始重新开始。