Since your cards do not intersect, you can simply scroll through the smaller card and insert more into it:
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
If you are using an old version of OCaml that does not include the cardinal feature, you can simply select one card to always iterate over it. As for the code above, is it used:
val fold : (key -> 'a -> 'b -> 'b) -> 'at -> 'b -> 'b
which basically iterates over all the elements of the map and calls a function that takes a key, value, and some other variable of type 'b and returns something from that type ( 'b ). In our case, we pass the IntMap.add function and that the other variable is our second map. Thus, it iterates over all elements and adds them to another map.
EDIT: you better do:
let disjoint_merge m1 m2 = IntMap.fold IntMap.add m1 m2
EDIT2: even better:
let disjoint_merge = IntMap.fold IntMap.add;;
I just looked at the implementation of cardinal , and it scans the tree and returns a counter. Thus, checking the sizes, you do O (n + m + min (n, m) log (max (n, m))) instead of just O (nlog (m)).
Niki Yoshiuchi
source share