【问题标题】:Iterating map of vectors of different sizes in C++C++中不同大小向量的迭代映射
【发布时间】:2015-12-17 21:46:43
【问题描述】:

所以我在 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。

【问题讨论】:

  • drawingPoints[j] 获取带有键 j 的条目,而不是 j-th 条目!
  • 是的,这就是我想要的,不是吗?取决于drawingPoints[ j ]处向量的大小 - 它会发生变化! - 我希望内部 for 循环同样频繁地执行。
  • 对于您的编辑,如果 int 只是指示条目数的索引,为什么不直接使用 std::vector&lt;stackPoints&gt;。然后你就可以做你已经做过的事情了。
  • 是的,你完全正确,我的错^^

标签: c++ dictionary vector


【解决方案1】:

出于多种原因,您应该使用迭代器。

  1. 您的地图可能不会包含从 0 到 drawingPoints.size() 的每个元素,并且对于在您循环时它不包含的每个元素,您将创建它。
  2. 您的最高条目可能大于drawingPoints.size(),在这种情况下您将永远无法达到。

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

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

这将创建一个您可以查看的迭代器(通过执行it-&gt; 或*it)。

更多信息可以在here找到。

【讨论】:

  • 我正要添加一个答案,建议在使用地图时使用迭代器,但你打败了我!
【解决方案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
   }
}

【讨论】:

    【解决方案3】:

    问题在于迭代映射:您可以执行drawingPoints[j] 完全是偶然的——您的映射键的类型恰好是int,所以j 作为它的索引可以正常工作。但是,并不是所有的js 都会在地图中包含任何内容,因此代码不起作用。

    以下是您迭代地图的方式:

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

    上面的例子需要 C++11。如果您使用较旧的编译器,请使用 this Q&A 使用迭代器遍历地图。

    【讨论】:

    • 我使用整数键作为计数器,所以当我添加另一对时我将它加 1。
    • @huzzm 确切地说,它添加了另一对,除非密钥恰好在那里,在这种情况下你迭代其对应的向量。
    • @huzzm 是的,它会工作。但是,如果按顺序迭代时键始终存在,那么最好使用向量向量,因为向量通常比映射更快且占用的内存更少。
    猜你喜欢
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-17
    • 1970-01-01
    • 2015-01-23
    • 2010-11-29
    • 2021-04-15
    相关资源
    最近更新 更多