双索引的最佳容器
设置允许双索引的容器的最佳方法(在 C++ 中)是什么? 具体来说,我有一个对象列表,每个对象都由一个键索引(每个键可能有多个)。 这意味着多重映射。 然而,这样做的问题在于,这意味着查找对象位置的线性查找可能比线性查找更糟糕。 我宁愿避免重复数据,因此让每个对象维护自己的坐标并必须在地图中移动自己会很糟糕(更不用说移动自己的对象可能会在成员函数中间接调用析构函数!)。 我宁愿有一些容器通过对象指针和坐标维护索引,并且对象本身保证稳定的引用/指针。 然后每个对象都可以将迭代器存储到索引(包括坐标),充分抽象,并知道它在哪里。 Boost.MultiIndex 似乎是最好的主意,但它非常可怕,而且我不希望我的实际对象需要是常量。
你会推荐什么?
编辑:Boost Bimap 看起来不错,但它提供稳定的索引吗? 也就是说,如果我更改坐标,对其他元素的引用必须保持有效。 我想使用指针进行索引的原因是因为对象没有内在排序,并且指针可以在对象更改时保持不变(允许其在 Boost MultiIndex 中使用,IIRC 确实提供了稳定的索引)。
What is the best way (in C++) to set up a container allowing for double-indexing? Specifically, I have a list of objects, each indexed by a key (possibly multiple per key). This implies a multimap. The problem with this, however, is that it means a possibly worse-than-linear lookup to find the location of an object. I'd rather avoid duplication of data, so having each object maintain it's own coordinate and have to move itself in the map would be bad (not to mention that moving your own object may indirectly call your destructor whilst in a member function!). I would rather some container that maintains an index both by object pointer and coordinate, and that the objects themselves guarantee stable references/pointers. Then each object could store an iterator to the index (including the coordinate), sufficiently abstracted, and know where it is. Boost.MultiIndex seems like the best idea, but it's very scary and I don't wany my actual objects to need to be const.
What would you recommend?
EDIT: Boost Bimap seems nice, but does it provide stable indexing? That is, if I change the coordinate, references to other elements must remain valid. The reason I want to use pointers for indexing is because objects have otherwise no intrinsic ordering, and a pointer can remain constant while the object changes (allowing its use in a Boost MultiIndex, which, IIRC, does provide stable indexing).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我根据您的文章做出几个假设:
我建议:
std::multimap
将键映射到对象指针,指向链表中的单个规范位置。std::map
由于您的文章提到“坐标”作为键,您可能还有兴趣阅读 查找 3D 坐标是否已使用的最快方法。
I'm making several assumptions based on your writeup:
I'd suggest:
std::multimap<Key, Object *>
that maps keys to object pointers, pointing to the single canonical location in the linked list.std::map<Object *, Key>
that allows looking up the key attached to a particular object. Make sure your code updates this map when the key is changed. (This could also be astd::multimap
if you need a many-to-many relationship.)Object
that contains the currentKey
(allowing O(1) lookups). Make sure your code updates this variable when the key is changed.Since your writeup mentioned "coordinates" as the keys, you might also be interested in reading the suggestions at Fastest way to find if a 3D coordinate is already used.
很难理解你到底在用它做什么,但它看起来像 boost bimap 就是你想要的。 除了特定的用例之外,它基本上是 boost 多索引,并且更易于使用。 它允许基于第一个元素或第二个元素进行快速查找。 为什么要通过地址查找地图中对象的位置? 使用抽象并让它为您完成所有工作。 请注意:映射中所有元素的迭代时间复杂度为 O(N),因此可以保证查找您正在考虑的方式为 O(N) (不是更糟)。
Its difficult to understand what exactly you are doing with it, but it seems like boost bimap is what you want. It's basically boost multi-index except a specific use case, and easier to use. It allows fast lookup based on the first element or the second element. Why are you looking up the location of an object in a map by its address? Use the abstraction and let it do all the work for you. Just a note: iteration over all elements in a map is O(N) so it would be guaranteed O(N) (not worse) to look up the way you are thinking of doing it.
一种选择是使用两个引用shared_ptr 的std::map。 像这样的事情可能会让你继续:
编辑:我刚刚注意到多重地图的要求,这仍然表达了这个想法,所以我会留下它。
One option would be to use two std::maps that referenced shared_ptrs. Something like this may get you going:
Edit: I just noticed the multimap requirement, this still expresses the idea so I'll leave it.