Kể từ khi bản đồ của bạn là rời nhau thì bạn có thể chỉ lặp qua các bản đồ nhỏ hơn và chèn vào lớn hơn:
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
Trong trường hợp bạn đang sử dụng một phiên bản cũ của OCaml mà không bao gồm các cardinal
chức năng bạn chỉ có thể chọn một bản đồ để luôn luôn lặp qua. Đối với những gì đoạn mã trên không, là nó sử dụng:
val fold : (key -> 'a -> 'b -> 'b) -> 'a t -> 'b -> 'b
Mà về cơ bản lặp qua tất cả các yếu tố bản đồ, và kêu gọi một chức năng mà phải mất một chìa khóa, giá trị và một số biến khác của loại 'b
và trả về một cái gì đó loại đó ('b
). Trong trường hợp của chúng ta, chúng ta chuyển hàm IntMap.add
và biến kia là bản đồ thứ hai của chúng ta. Vì vậy, nó lặp qua tất cả các phần tử và thêm chúng vào bản đồ khác.
EDIT: Bạn đang tốt hơn hết chỉ cần thực hiện:
let disjoint_merge m1 m2 =
IntMap.fold IntMap.add m1 m2
EDIT2: thậm chí tốt hơn:
let disjoint_merge = IntMap.fold IntMap.add;;
Tôi chỉ nhìn vào thực hiện cardinal
và nó đi cây và trả về số lượng. Vì vậy, bằng cách kiểm tra kích cỡ bạn đang làm O (n + m + min (n, m) log (tối đa (n, m))) thay vì chỉ O (n log (m)).
Nguồn
2010-09-20 18:58:35
Khi loại cho khóa là 'int' và bạn quan tâm đến việc hợp nhất (phân tách hoặc không) bản đồ, bạn nên kiểm tra xem bản đồ có được hiển thị là cây Patricia phù hợp với nhu cầu của bạn hay không. Sau đây là cách triển khai: http://www.lri.fr/~filliatr/ftp/ocaml/ds/ptmap.ml.html –
Nhân tiện, nếu một trong những câu trả lời được giải quyết thì bạn nên đánh dấu nó là đã được chấp nhận. –