访问std::map中元素的最有效方法是什么

What is the Most Efficient Way to Access Elements in an std::map?

本文关键字:有效 方法 是什么 元素 std map 访问      更新时间:2023-10-16

我有一个std::map<some_type, std::vector<another_type>>作为类中的静态变量。我希望所述类的对象对应于映射的向量中的元素。我当时的想法是只使用迭代器来存储向量和映射,但我也考虑存储键的副本,这样我就可以使用map::find来查找与之相关的值。推荐哪种方式更有效?

代码

class example_class
{
private:
static std::map<some_type, std::vector<another_type>> my_list;
some_type::iterator map_it;
// I could either use this
std::vector<another_type>::iterator location_in_vector_it;
// or this
some_type copy_of_key;
public:
// the constructor creates a new element, or adds the value to the end
// of the vector in the preexisting element.
example_class(key, val);
};

推荐的方法是编写正确、易于理解且有意义的代码。关于效率:

  • 如果vector可以增长,则存储vector的迭代器是个坏主意,因为vector::insert可以生成无效的迭代器
  • 将索引存储到vector中(如果这是一个选项——这些向量如何改变?)允许在O(1)时间内获得元素,但在您的情况下,您仍然需要找到向量。

  • 存储map的迭代器将允许您在O(1)时间内找到向量,并且该迭代器在修改map后仍然有效(除非您删除迭代器指向的条目)。

    • map中存储对vector的引用类似于使用迭代器,并且可能导致更可读的代码
  • 存储密钥并使用map::find可以在O(lg n)时间内找到向量。这种方法可以处理您要查找的矢量已从map中删除的情况

因此最安全的方法是存储键和索引,并编写代码来处理找不到元素的情况。但是<这是应该发生的事情吗>你想让其他人(可能是另一个相同类型的对象)删除你对象的元素吗?可能不会,因为每个对象都应该"对应于一个元素"。这是你的设计有问题吗?

如果我这样做,我可能想确保我的对象元素不会被粗暴地拿走。一种方法是使用共享指针。我可能会考虑存储std::vector<std::shared_ptr<another_type>>,而不是将std::vector<another_type>存储在map中。根据对象销毁时应该发生的情况,我可能会将shared_ptr更改为weak_ptr,这样静态容器就不会维护不再存在的对象的数据。在任何一种情况下,每个对象都可以为其元素维护自己的shared_ptr。这允许快速访问元素,并确保元素不会在对象被破坏之前被破坏

当然,最理想的方法取决于您需要将这些元素存储在静态容器中的原因。

如果my_list的大小发生变化(除非您之前保留了所有内容),则无法将迭代器存储到my_list中的向量。

最简单的方法是先在向量中存储关键字,然后再存储索引,假设您只推送新元素,而从不删除旧元素。最好的是带有索引的映射中的迭代器。