我目前正在研究Haskell API。后者提供了一些当前以列表作为输入的函数,即[(String,[(String, Double)])]
。
出于可视化目的,这里是上面提到的列表的示例:
[
("A", [
("I1", 1),
("I2", 2),
]
),
("B", [
("I1", 3),
]
)
]
我已经定义了一些私有辅助函数。一个辅助函数将搜索此列表中的特定条目(Data.List.find
= O(n)
);另一个将执行交叉点;另一个函数将上面列出的列表转换为以下列表:
[
("I1", [
("A", 1),
("B", 3),
]
),
("I2", [
("A", 2),
]
)
]
执行转换的函数使用Data.Map
,因为它提供了一些可以简化该过程的函数,例如Data.Map.unionWith
和Data.Map.insertWith
。好吧,因为转换函数必须调用Data.Map.fromList
和Data.Map.toList
,我认为有一个地图地图而不是列表列表< / em>从一开始。所以我更改了我的示例输入以匹配地图要求。
同样,出于可视化目的,这里是上面的列表地图地图:
Map.fromList [
("A", Map.fromList [
("I1", 1),
("I2", 2),
]
),
("B", Map.fromList [
("I1", 3),
]
)
]
感谢这一步,我的代码丢失了几行,感谢Data.Map.lookup
,现在找到所需的代码只需要O(log n)
次。
尽管如此,我现在问自己这是否真的是一个很好的解决方案?是地图地图的方法吗?或者转换功能是否适用于Data.Map.fromList
和Data.Map.toList
,其余部分是否可以使用列表列表?或者更好的是,是否存在更适合此类工作的数据结构?
我真的很期待你的回复。
答案 0 :(得分:4)
地图地图的初始化仍然只需要O(n)
。
首先考虑列表清单。
假设外部列表是[a 1 , 2 ,..., p ],每个内部项目是a j =(l j ,[b 0 ,b 1 ,...,b q j ])。然后构建列表列表需要O(n =Σ j = 1 p q j )。
初始化内部地图需要m j 。 = O(q j )。初始化映射图需要O(Σ j = 1 p m j )= O(n)。
答案 1 :(得分:4)
这闻起来像图和边缘。一种稍微不同的方法,可能会或可能不会工作,是重新设计您的问题,而不是[(String,[(String,Double)])]
而是简单地操作2元组的字符串。然后您有[((String, String), Double)]
,结果地图的类型为Data.Map.Map (String, String) Double
。
或者,如果字符串键的空间有限,并且因此可以有效地映射到机器int,请查看使用IntMap。与映射相同的语义,除了键必须是机器整数(Int32或Int64)。会有更好的表现。
答案 2 :(得分:2)
当然这取决于您的实际数据,但也许您可以使用Multimap代替?有些实现浮动(例如http://hackage.haskell.org/packages/archive/Holumbus-Distribution/0.0.1.1/doc/html/Holumbus-Data-MultiMap.html),但我没试过它们。