提问人:huzzm 提问时间:12/18/2015 最后编辑:huzzm 更新时间:12/18/2015 访问量:1047
在 C++ 中迭代不同大小的向量映射
Iterating map of vectors of different sizes in C++
问:
所以我用 C++ 声明了以下映射:
typedef vector<Vector2D> stackPoints;
typedef map<int, stackPoints> mapPoints;
mapPoints drawingPoints;
给它加值后,我想输出其中的所有元素,但是不同关键位置的向量大小不一样:
我正在使用以下两个不起作用的 for 循环。有时程序在运行时崩溃,并给我超出范围的矢量错误。
for (int j = 0; j < drawingPoints.size(); j++)
{
for (int i = 0; i < drawingPoints[j].size(); i++)
{
cout << "(...)" << endl
}
}
在我看来,内部 for 循环经历了恒定的次数,就好像以下情况是不可能的:
1) 第一个向量的大小为 1,因此内部 for 循环将执行一次。
2) 然后地图的第二个向量的大小为 5,现在我希望 for 循环经过 5 次,但这似乎不起作用。
**编辑**
我使用整数键作为计数器,因此当我添加另一对时,我会将其递增 1。
答:
1赞
Sergey Kalinichenko
12/18/2015
#1
问题在于迭代地图:你可以这样做的事实完全是偶然的 - 你的地图键的类型恰好是 ,所以作为它的索引工作得很好。但是,并非所有 s 都会在映射中包含任何内容,因此代码不起作用。drawingPoints[j]
int
j
j
以下是遍历地图的方式:
for(auto& kvp : drawingPoints) {
cout << "Key " << kvp.first << " has the following values:" << endl;
for (auto n : kvp.second) {
cout << n << " ";
}
cout << endl;
}
上面的示例需要 C++11。如果您使用较旧的编译器,请使用此 Q&A 使用迭代器遍历映射。
评论
0赞
huzzm
12/18/2015
我使用整数键作为计数器,因此当我添加另一对时,我会将其递增 1。
0赞
Sergey Kalinichenko
12/18/2015
@huzzm确切地说,它添加了另一对,除非键恰好在那里,在这种情况下,你要遍历它对应的向量。
0赞
Sergey Kalinichenko
12/18/2015
@huzzm 是的,它会起作用。但是,如果按顺序迭代时键始终存在,则最好使用向量的向量,因为向量通常比映射更快,占用的内存更少。
2赞
R Sahu
12/18/2015
#2
for (int j = 0; j < drawingPoints.size(); j++)
{
// This is wrong.
// j is not necessarily a valid key in the map.
for (int i = 0; i < drawingPoints[j].size(); i++)
{
cout << "(...)" << endl
}
}
使用迭代器来避免此类问题。
mapPoints::iterator map_begin = drawingPoints.begin();
mapPoints::iterator map_end = drawingPoints.end();
for ( ; map_begin != map_end; ++map_iter )
{
stackPoints::iterator v_iter = map_iter->second.begin();
stackPoints::iterator v_end = map_iter->second.end();
for ( ; v_iter != v_end; ++v_iter )
{
cout << "(...)" << endl
}
}
如果您使用的是 C++11 编译器,则可以使用:
for ( auto& map_item : mapPoints )
{
for ( auto& v_item : map_item.second )
{
cout << "(...)" << endl
}
}
2赞
Fantastic Mr Fox
12/18/2015
#3
出于多种原因,您应该使用迭代器。
- 您的地图可能不包含从 0 到 的每个元素,对于它不包含的每个元素,当您遍历它时,您将创建它。
drawingPoints.size()
- 您的最高条目可能更大,在这种情况下,您将永远无法达到它。
drawingPoints.size()
让我们看一下最外层的循环,如果你想为它定义一个迭代器,你应该做以下事情:
for (mapPoints::Iterator it = drawingPoints.begin(); it != drawingPoints.end(); it++) {
这将创建一个迭代器,您可以查看该迭代器(通过执行 或 )。it->
*it
更多信息可以在这里找到。
评论
0赞
Francis Cugler
12/18/2015
我正要添加一个答案,建议在使用地图时使用迭代器,但你打败了我!
评论
drawingPoints[j]
获取带有 key 的条目,而不是 -th 条目!j
j
std::vector<stackPoints>