我有一个简单的union-find代码,如下所示:
let rec find p x =
if p.(x) = x
then x
else
let y = find p (p.(x)) in
p.(x) <- y;
y;;
let union x y p =
p.(find p y) <- p.(find p x);
p
示例:
let a = [|0;1;2;3;4|]
let print_array a =
Array.iter (fun i -> Printf.printf "%i" i; print_string " ") a
let print_union =
let a = union 0 1 a in
print_string "Result union (0, 1): ";
print_array a;
print_string "\n"
结果将是:
Result union (0, 1): 0 0 2 3 4
我很难进一步得到不相交的东西。
例如,上面的示例我想得到:{0,1},{2},{3},{4}
感谢您的帮助。
答案 0 :(得分:1)
由于显而易见的原因,您无法通过整个结构打印该结果。
所以,你想收集所有工会的居民 - 发现:
let print_classes a =
(* Let's first create an array for storing the classes *)
let classes = Array.make (Array.length a) [] in
(* Let's now populate it!
I'm going backwards in the array to have nicer printing *)
for i = (Array.length classes) - 1 downto 0
do classes.(a.(i)) <- i :: (classes.(a.(i))) done;
(* And now the printing *)
Array.iter (function
| [] -> ()
| h::t -> Printf.printf "{%d%a}" h
(fun c -> List.iter (fun x -> Printf.fprintf c ",%i" x)) t
)
classes
为了简洁起见,我使用了Printf功能,你可以找到他们的文档here。
请注意,这可能会有所改进,因为它会创建一个可能很大的数组,而且几乎不会#34;填充。根据您使用此功能的频率,您可能希望将等价类与类别负责人一起存储(我必须这样做一次,我使用了Set
和Map
来自stdlib)。