C++ STL“关联集/映射”
我正在寻找特定类型的集合/映射的名称,希望有一些现有代码,例如 C++ STL。
调用集合A
。
我想运行以下命令:
A.associate(3,5)
A.associate(3,6)
A.associate(6,8)
A.associate(8,10)
A.associate(4,9)
然后能够提出以下问题,并收到指示的答案:
A.is_associated(3,5) -> True
A.is_associated(5,10) -> True
A.is_associated(10,3) -> True
A.is_associated(4,10) -> False
您知道这种构造/集合的名称吗?
你知道是否有现有的 C/C++ 实现吗?
I'm looking for the name of a particular kind of set/map, for which there is hopefully some existing code, such as the C++ STL.
Call the set A
.
I would like to run the following commands:
A.associate(3,5)
A.associate(3,6)
A.associate(6,8)
A.associate(8,10)
A.associate(4,9)
And then be able to ask the following questions, receiving the answers indicated:
A.is_associated(3,5) -> True
A.is_associated(5,10) -> True
A.is_associated(10,3) -> True
A.is_associated(4,10) -> False
Do you know the name of this kind of construct/set?
Do you know if there is an existing C/C++ implementation?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
一般来说,我认为这个数据结构是一个图:也就是说,在您的情况下使用整数标识的一组节点,以及一组可能是有向节点对的边。根据您的具体需求,有多种表示方法和图表。 Boost有许多典型的图数据结构以及在它们上运行的算法集合。
基于评论中的一些说明: is_linked() 操作是无向图中的路径搜索。根据图的需要,可以添加边来表示数据结构,使得 is_linked() 是常数时间,但代价是插入线性时间。
In general I think this data structure is a graph: that is, a set of nodes which are in your case identified using integer, and a set of edges which are possibly directed pairs of nodes. There are many ways to represent and graphs depending on your specific needs. Boost has a number of typical graph data structure plus a collection of algorithms operating on them.
Based on some the clarifications in the comments: the
is_associated()
operation is a path search in an undirected graph. Depending on the graph's need, adding edge can be made to represent the data structure such thatis_associated()
is constant time at the cost of insertion costing linear time.编辑:如果您想采取额外的步骤,您应该考虑有效实施不相交集并查。
不幸的是,我看到的唯一明智的方法是在
std::sets
上创建std::map
——你需要每次插入时检查这两个元素是否在不同的子集——如果是这样,则将它们合并。因此,外部集合存储所有元素并将它们指向它们所属的集合。
现在,如果您添加一个新关联:
现在 is_linked 函数非常快——只需检查两个元素是否属于同一集合即可。
用英语:
可能是这样的:
会有错误和错误,我只有记事本可用(无论如何都花了太多时间在这上面)。
添加的时间复杂度为
O(n)
(但通过使用额外的间接层可能会减少到O(log(n))
(并摆脱愚蠢的映射循环)查询的时间为O(log(n))
。使用
unordered_set/unordered_map
可以将两者都减少到O(1)
摊销。Edit: if you want to go the extra step, you should think about an efficient implementation of Disjoint-set Union-Find.
Unfortunately the only sane way I see is making a
std::map
overstd::sets
-- you need to check each time at insert, whether the two elements are in different subsets -- if so, you merge them.So the outer set stores all elements and points them to the sets they belong to.
Now if you add a new association:
Now the is_associated function is really fast -- just check if the two elements belong to the same set.
In english:
Something maybe like this:
There will be errors and bugs, I have just notepad available (and spent too much time on this anyway).
Adding is
O(n)
(but might be reduced toO(log(n))
by using an additional layer of indirection (and getting rid of the stupid map loop). Query isO(log(n))
.Using
unordered_set/unordered_map
you might reduce both toO(1)
amortized.