Пока я опубликую свою собственную реализацию (просто операция объединения), я использую функциональный язык, поэтому будьте осторожны... это может сбивать с толку:
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 list
.
Синтаксис прост, каждая строка представляет один случай, в котором 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
как элемент окончательного ответа и начинаю снова с пустого.
person
Jack
schedule
10.07.2010