Поскольку ваши карты не пересекаются, вы можете просто перебрать меньшую карту и вставить в большую:
let disjoint_merge m1 m2 =
if (IntMap.cardinal m1) < (IntMap.cardinal m2) then
IntMap.fold IntMap.add m1 m2
else
IntMap.fold IntMap.add m2 m1
В случае, если вы используете более старую версию OCaml, в которой нет функции cardinal
, вы можете просто выбрать одну карту, через которую вы всегда будете проходить. Что касается приведенного выше кода, он использует:
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
, который в основном перебирает все элементы карты и вызывает функцию, которая принимает ключ, значение и некоторую другую переменную типа 'b
и возвращает что-то такого типа ('b
). В нашем случае мы передаем функцию IntMap.add
, и эта другая переменная является нашей второй картой. Поэтому он перебирает все элементы и добавляет их на другую карту.
РЕДАКТИРОВАТЬ: Вам лучше всего делать:
let disjoint_merge m1 m2 =
IntMap.fold IntMap.add m1 m2
EDIT2: еще лучше:
let disjoint_merge = IntMap.fold IntMap.add;;
Я только что посмотрел на реализацию cardinal
, и она обходит дерево и возвращает счет. Таким образом, проверяя размеры, вы делаете O (n + m + min (n, m) log (max (n, m))) вместо просто O (n log (m)).