通过索引访问地图值?

时间:2011-02-11 03:30:10

标签: c++ map

我有这张地图:

m.insert(pair<int, string>(10, "map1"));
m.insert(pair<int, string>(11, "map2"));
m.insert(pair<int, string>(12, "map3"));
m.insert(pair<int, string>(13, "map4"));
m.insert(pair<int, string>(14, "map5"));

然后,我让用户输入一个数字:

Please select:
1. Map1
2. Map2
3. Map3
4. Map4
5. Map5

假设用户输入3,我该如何得到这个值:12 ??

4 个答案:

答案 0 :(得分:4)

使用当前的设置,没有简单的方法可以做到这一点;你必须迭代地图的所有元素,寻找那个Map3作为值的元素。

map已针对在一个方向上查找关系进行了优化。给定map<K, V>,您可以轻松地从K s映射到V s,但不能相反。原因是因为您可以将任何V存储为值,所以无法保证您将获得唯一的逆。也就是说,给出这张地图:

 0 -> 0
 1 -> 0 
 2 -> 1

没有任何有意义的方法可以说出哪个键的值为0;有两个这样的键,0和1。

这里有很多选择。首先,您可以转动map,而不是将字符串与整数相关联,而不是将整数与字符串相关联。根据您的使用案例,这似乎是您想要做的第一个。如果你这样做,那么你可以使用方括号运算符来查找相关的值:

cout << m["Map3"] << endl;

或者,如果您担心丢失值会发生什么,那么您可以编写

map<string, int>::iterator itr = m.find("Map3");
if (itr != m.end()) {
    /* ... use itr to read the values ... */
}

或者,如果你真的必须有从整数到字符串的映射,并且你知道每个整数与唯一字符串配对,反之亦然(也就是说,地图是双射),那么你可以使用一个Boost.Bimap来编码这种双向关系。这样可以很容易地在键和值之间来回切换。

希望这有帮助!

答案 1 :(得分:3)

std::map不会跟踪其元素的插入顺序;元素以排序顺序而不是插入顺序存储。如果需要跟踪插入元素的顺序,则需要自己执行此操作。一种方法是使用std::vector保留第二个按顺序存储密钥的容器,例如:

std::vector<int> insertion_order;

m.insert(std::make_pair(10, "map1"));
insertion_order.push_back(10);

然后,N插入元素的键位于N - 1序列中的索引insertion_order

答案 2 :(得分:2)

将菜单中的整数映射到您要存储的数据。考虑:

struct data {
    data(int n, const std::string& s) : s(s), n(n) { }
    std::string s;
    int n;
};

// ...
std::map<int,data> m;
m.insert(make_pair(1, data(10, "Map1"));
m.insert(make_pair(2, data(11, "Map2"));
m.insert(make_pair(3, data(12, "Map3"));

int n = m[3].n;  // 12

答案 3 :(得分:0)

来自文档:

  

比较:比较类:一个类,它接受键类型的两个参数并返回一个bool。表达式comp(a,b),其中comp是此比较类的对象,a和b是键值,如果要在严格的弱排序操作中将a放置在比b更早的位置,则返回true 。这可以是实现函数调用操作符的类,也可以是指向函数的指针(请参阅构造函数)。 默认为less<Key>,其返回与应用小于运算符(a<b)相同。   map对象使用此表达式来确定容器中元素的位置。地图容器中的所有元素都始终遵循此规则进行排序。

因此,map类不像数组那样维护其元素的顺序。如果有一个索引操作符,它希望 not 返回添加到地图中的第i个元素。它是一个关联集合,当您需要根据插入时间维护订单时,通常不会使用该类型的数据结构。