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

Iterating map of vectors of different sizes in C++

本文关键字:向量 迭代 映射 C++      更新时间:2023-10-16

所以我在C++中声明了以下映射:

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

在给它添加值后,我想输出其中的所有元素,但不同关键位置的向量大小不同:

对于不起作用的循环,我使用以下两个。有时程序在运行时崩溃,并给我超出范围的矢量错误。

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. 您的映射可能不包含从0到drawingPoints.size()的每个元素,当您在映射上循环时,您将为每个不包含的元素创建映射
  2. 您的最高入口可能大于drawingPoints.size(),在这种情况下,您将永远无法达到它

让我们看看最外层的循环,如果你想为它定义一个迭代器,你应该做以下事情:

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

这将创建一个迭代器,您可以查看它(通过执行it->*it)。

更多信息可以在这里找到。

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

问题在于迭代映射:可以执行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&使用迭代器遍历地图。