按索引访问地图值

时间:2011-10-21 23:49:29

标签: c++ stl map

如果我有像

这样的结构
std::map<string, int> myMap;
myMap["banana"] = 1;
myMap["apple"] = 1;
myMap["orange"] = 1;

如何访问myMap [0]?

我知道地图在内部进行排序,我对此很好,我希望通过索引在地图中获取值。我已经尝试了myMap [0]但是我得到了错误:

Error   1   error C2679: binary '[' : no operator found which takes a right-hand operand of type 'int' (or there is no acceptable conversion)   

我意识到我可以做这样的事情:

string getKeyAtIndex (int index){
    map<string, int>::const_iterator end = myMap.end(); 

    int counter = 0;
    for (map<string, int>::const_iterator it = myMap.begin(); it != end; ++it) {
        counter++;

        if (counter == index)
            return it->first;
    }
}

但这肯定是非常低效的?有没有更好的办法?

6 个答案:

答案 0 :(得分:22)

您的map不应该以这种方式访问​​,它由键而不是位置索引。 map迭代器是双向的,就像list一样,因此您使用的函数不比按位置访问list效率低。您可以使用std::advance( iter, index )begin()开始的帮助来编写您的函数。如果您希望按位置随机访问,请使用vectordeque

答案 1 :(得分:4)

上一个答案(见评论):仅myMap.begin();

怎么样

您可以使用矢量后备存储来实现随机访问映射,后者实际上是一对矢量。当然,您当然会失去标准库映射的所有好处。

答案 2 :(得分:4)

可能有实现特定(非便携)方法来实现您的目标,但不是可移植的方法。

通常,std::map实现为一种二叉树,通常按键排序。第一个元素的定义因顺序而异。另外,在你的定义中,元素[0]是树顶部的节点还是最左边的叶子节点?

许多二叉树被实现为链表。大多数链接列表不能像数组一样直接访问,因为要查找元素5,您必须按照链接进行操作。这是定义。

您可以同时使用std::vectorstd::map

来解决您的问题
  1. 从动态内存中分配对象。
  2. 将指针与密钥一起存储到std::map
  3. 将指针存储在std::vector所需的位置 在
  4. std::map将允许一种有效的方法来按键访问对象 std::vector将允许通过索引访问对象的有效方法。 存储指针只允许对象的一个​​实例,而不必维护多个副本。

答案 3 :(得分:3)

嗯,实际上你不能。你找到的方式效率非常低,它的计算复杂度为O(n)(n运算最坏情况,其中n是映射中元素的数量)。

通过比较访问向量或数组中的项具有复杂度O(1)(常数计算复杂度,单个操作)。

考虑到地图在内部实现为红黑树(或avl树,它取决于实现),每次插入,删除和查找操作都是O(log n)最坏的情况(它需要在base 2操作中以对数为单位)在树中找到一个元素,这是非常好的。

您可以处理的方法是使用包含矢量和地图的自定义类。 类末尾的插入将平均为O(1),按名称查找将为O(log n),按索引查找将为O(1),但在这种情况下,删除操作将为O(n)。 / p>

答案 4 :(得分:2)

std::map是一个有序的容器,但是它的迭代器不支持随机访问,而是双向访问。因此,您只能通过导航其所有先前元素来访问第n个元素。您的示例的一个简短替代方法是使用标准迭代器库:

 std::pair<const std::string, int> &nth_element = *std::next(myMap.begin(), N);

这具有线性复杂度,如果您打算在大型地图中经常使用这种方式,则不太理想。

一种替代方法是使用支持随机访问的有序容器。例如,boost::container::flat_map提供了一个成员函数nth,它使您可以精确地找到所需的内容。

答案 5 :(得分:1)

你可以使用像容器这样的其他地图 保持大小字段可以使二叉搜索树易于随机访问 这是我的实施......
标准样式,随机访问迭代器...
大小平衡树...
https://github.com/mm304321141/zzz_lib/blob/master/sbtree.h
和B +树......
https://github.com/mm304321141/zzz_lib/blob/master/bpptree.h