在STL映射中的所需位置插入元素

时间:2012-01-13 07:23:49

标签: c++ stl map iterator

map <int, string> rollCallRegister;
map <int, string> :: iterator rollCallRegisterIter;
map <int, string> :: iterator temporaryRollCallRegisterIter;

rollCallRegisterIter     = rollCallRegister.begin ();
tempRollCallRegisterIter = rollCallRegister.insert (rollCallRegisterIter, pair <int, string> (55, "swati"));

rollCallRegisterIter++;
tempRollCallRegisterIter = rollCallRegister.insert (rollCallRegisterIter, pair <int, string> (44, "shweta"));

rollCallRegisterIter++;
tempRollCallRegisterIter = rollCallRegister.insert (rollCallRegisterIter, pair <int, string> (33, "sindhu"));

// Displaying contents of this map.
cout << "\n\nrollCallRegister contains:\n";
for (rollCallRegisterIter = rollCallRegister.begin(); rollCallRegisterIter != rollCallRegister.end(); ++rollCallRegisterIter)
{
    cout << (*rollCallRegisterIter).first << " => " << (*rollCallRegisterIter).second << endl;
}

输出:

rollCallRegister contains:
33 => sindhu
44 => shweta
55 => swati

我增加了迭代器。为什么它仍然排序?如果该位置应该由地图自行更改,那么提供迭代器的目的是什么?

4 个答案:

答案 0 :(得分:3)

因为std::map是一个已排序的关联容器。

  

在地图中,键值通常用于唯一标识元素,而映射值是与此键关联的某种值。

根据here位置参数是

  

要插入的第一个要比较的元素的位置   操作。请注意,这不会强制新元素进入   地图容器中的位置(总是在一个集合中的元素)   遵循特定的顺序),但这实际上是一个指示   容器中可能的插入位置,如果设置为   元素位于元素所在的实际位置之前的元素   插入,使插入操作非常有效。迭代器是   成员类型,定义为双向迭代器类型。

因此,此参数的目的主要是通过缩小元素范围来略微提高插入速度。

如果插入顺序很重要,您可以使用std::vector<std::pair<int,std::string>>

答案 1 :(得分:3)

界面确实有点令人困惑,因为它看起来非常像std::vector<int>::insert(例如)但却没有产生相同的效果......

对于关联容器,例如setmap和新的unordered_set和co,您完全放弃对元素顺序的控制(通过迭代容器看到) )。作为对这种失控的交换,您可以获得有效的查询。

突然让你控制插入是没有意义的,因为它会让你破坏容器的不变量,你会失去有效的查找,这是首先使用这些容器的原因。

因此insert(It position, value_type&& value)不会插入所述位置......

然而,这为我们提供了一些优化空间:在关联容器中插入元素时,需要执行查找以找到插入此元素的位置。通过让您指定提示,您将有机会帮助容器加快流程。

这可以用一个简单的例子来说明:假设你收到的元素已经通过某种界面排序了,不使用这些信息会很浪费!

template <typename Key, typename Value, typename InputStream>
void insert(std::map<Key, Value>& m, InputStream& s) {
  typename std::map<Key, Value>::iterator it = m.begin();

  for (; s; ++s) {
    it = m.insert(it, *s).first;
  }
}

有些项目可能没有很好的排序,但无关紧要,如果两个连续的项目顺序正确,那么我们将获益,否则......我们将照常执行。

答案 2 :(得分:1)

地图始终排序,但您可以提供“提示”,了解该元素可作为优化的位置。

插入是O(log N),但是如果你能够成功地告诉容器去哪里,那就是恒定时间。

因此,如果您要创建一个已经排序的值的大容器,那么每个值都将在最后插入,尽管树需要重新平衡很多次。

答案 3 :(得分:0)

正如sad_man所说,它是联想的。如果使用现有密钥设置值,则覆盖以前的值。

现在迭代器是必需的,因为你通常不知道键是什么。