Không xa như tôi biết. Bạn phải viết một hàm truyền tải đồ thị.
Trước tiên, hãy quyết định nơi để phá vỡ vòng tròn. Trong trường hợp này nó là tầm thường: sử dụng các tên nút (giả sử chúng là duy nhất trong một biểu đồ). Đối với một cấu trúc phức tạp hơn, chẳng hạn như một biểu đồ có các nút và các cạnh riêng biệt, bạn sẽ phải quyết định có lưu trữ các cạnh với các nút, các nút có cạnh hay giữ các nút và các cạnh hoàn toàn riêng biệt hay không.
Sau đó liệt kê tất cả các nút trong biểu đồ. Trong trường hợp này, cách rõ ràng là duyệt qua các biểu đồ thu thập các nút trong một bản đồ hữu hạn (xem Data.Map). Sau đó lưu trữ mỗi nút dưới dạng tên theo sau là danh sách các tên nút khác.
Khôi phục biểu đồ có nghĩa là sử dụng mẫu "buộc nút". Đọc biểu đồ được lưu trữ thành một cấu trúc của [(String, [String])]. Sau đó, đồ thị ban đầu có thể được xây dựng lại với mã sau:
import qualified Data.Map as M
data Node = Node String [Node]
instance Show Node where
show (Node name others) = "Node " ++ show name ++
" " ++ show (map nodeName others)
where nodeName (Node n _) = n
restoreGraph :: [(String, [String])] -> M.Map String Node
restoreGraph pairs = table
where
table = M.fromList $ map makeNode pairs
makeNode (name, others) = (name, Node name $ map findNode others)
findNode str = fromJust $ M.lookup str table
Lưu ý đệ quy lẫn nhau: gọi bảng makeNode, gọi hàm findNode, gọi bảng. Thanks to lazy evaluation this does the Right Thing.
Chỉnh sửa: mã hiện đã được kiểm tra và mở rộng một chút.
Nguồn
2008-12-28 07:02:47