简体   繁体   English

C ++中不同大小的向量的迭代图

[英]Iterating map of vectors of different sizes in C++

So I declared the following map in C++: 因此,我在C ++中声明了以下映射:

typedef vector<Vector2D> stackPoints; 
typedef map<int, stackPoints> mapPoints; 
mapPoints drawingPoints;

After adding values to it, I want to output all the elements in it, but the vectors at the different key positions are not of the same size: 向其添加值之后,我想输出其中的所有元素,但是不同键位置上的向量的大小不同:

I am using the following two for-loops that don't work. 我正在使用以下两个不起作用的for循环。 Sometimes the program crashes at runtime and gives me the out of range vector error. 有时,程序在运行时崩溃,并给了我超出范围的矢量错误。

for (int j = 0; j < drawingPoints.size(); j++)
{
    for (int i = 0; i < drawingPoints[j].size(); i++)
    {
        cout << "(...)" << endl
    }
}

It seems to me that the inner for-loop has the be went through a constant amount of times, as if the following scenario wasn't possible: 在我看来,内部for循环已经历了恒定的时间,好像不可能出现以下情况:

1) The first vector has a size of 1, so the inner for-loop will be executed once. 1)第一个向量的大小为1,因此内部for循环将执行一次。

2) Then the second vector of the map has a size of 5 and now I want the for-loop to be went through 5 times, but this seems to not work. 2)然后,地图的第二个向量的大小为5,现在我希望for循环经过5次,但这似乎不起作用。

** Edit ** **编辑**

I am using the integer key as a counter, so I increment it by 1 when I add another pair. 我使用整数键作为计数器,因此当我添加另一对时,我将其递增1。

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
    }
}

Use iterators to avoid such issues. 使用迭代器可以避免此类问题。

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
   }
}

If you are using a C++11 compiler, you can use: 如果使用的是C ++ 11编译器,则可以使用:

for ( auto& map_item : mapPoints )
{
   for ( auto& v_item : map_item.second )
   {
      cout << "(...)" << endl
   }
}

For multiple reasons you should be using an iterator. 由于多种原因,您应该使用迭代器。

  1. Your map may not contain every element from 0 to drawingPoints.size() and for each element that it doesnt contain when you loop over it you will create it. 您的地图可能不包含从0到drawingPoints.size()的每个元素,并且当您对其进行循环时,您将为其创建的不包含的每个元素。
  2. Your highest entry may be greater then drawingPoints.size() in which case you will never reach it. 您的最高条目可能大于drawingPoints.size()在这种情况下,您将永远无法达到它。

Lets look at outer most loop, if you want to define an iterator for it you should do the following: 让我们看一下最外层的循环,如果要为其定义一个迭代器,则应执行以下操作:

for (mapPoints::Iterator it = drawingPoints.begin(); it != drawingPoints.end(); it++) {

This creates an iterator which you can look at (by doing it-> or *it ). 这将创建一个您可以查看的迭代器(通过执行it->*it )。

More information can be found here . 可以在此处找到更多信息。

The problem is iterating the map: the fact that you can do drawingPoints[j] is entirely by accident - the type of your map's key just happens to be int , so j works fine as its index. 问题是迭代地图:您可以执行drawingPoints[j]完全是偶然的事实-地图键的类型恰好是int ,因此j可以很好地用作索引。 However, not all j s are going to have anything in the map, so the code does not work. 但是,并非所有j都将在映射中包含任何内容,因此该代码不起作用。

Here is how you iterate over your map: 这是您遍历地图的方式:

for(auto& kvp : drawingPoints) {
    cout << "Key " << kvp.first << " has the following values:" << endl;
    for (auto n : kvp.second) {
        cout << n << " ";
    }
    cout << endl;
}

The example above requires C++11. 上面的示例需要C ++ 11。 If you use an older compiler, use this Q&A to go over a map using iterators. 如果您使用的是较旧的编译器,请使用此问答,以使用迭代器遍历地图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM