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